【问题标题】:How to program an application with unknown future modifications and features?如何编写具有未知未来修改和功能的应用程序?
【发布时间】:2011-03-22 08:59:59
【问题描述】:

背景

我对编程并不陌生,但在处理客户及其需求方面我是新手。这是我与当前客户的历史:我继承了一个 PHP 应用程序,它已完成 2/3,继续使其 100% 完成,直到客户需要导致应用程序和数据库需要重写的(主要)功能。我花了两周时间起草新应用程序如何与新更改以及其他所需功能一起使用,在获得批准后,我再次开始构建应用程序。我现在被要求添加在新版本之前没有讨论过的新功能——而且,它们非常重要。此外,整个应用程序拥有 300 多个用户,这使得它变得更加困难。

问题

忽略客户要求最初未讨论的功能这一事实。如何制作我构建的应用程序功能证明?在一个完美的世界中,客户会确切地知道应用程序应该具有哪些功能,这将使我的工作更容易完成。但事实并非如此,我所说的这些主要功能是在起草应用程序时应该包含的那些,而不是在应用程序上线时包含的那些——尽管这个问题对于未来对应用程序的任何修改或特性来说都是一般性的。

我不喜欢告诉我的客户他要求的功能或更改非常重要,以至于我不得不(再次)重写整个应用程序。但是,在写这篇文章时,我突然想到,如果不重新开始就无法添加该功能,这可能不是我的错。但这似乎几乎是他想要的任何新功能,因为有些东西已经为应用程序硬编码,现在更改它们以获得新功能是行不通的。

任何与这种情况有关的个人经历都会很棒 - 我希望我不是唯一一个处理这种情况的人,因为它可能非常令人沮丧。谢谢!

【问题讨论】:

    标签: php web-applications client future-proof


    【解决方案1】:

    请放心,这是一个老问题。大多数程序员不得不与每天对应用程序有新愿景的经理或决策者打交道。他们似乎不明白,自动化某些东西比在高层次上描述它需要更多的工作。他们似乎也不明白,被告知拆除您刚刚辛勤工作的东西会损害员工的士气。

    尝试预测可能要求重新设计软件的所有方式是一个难题。有些人建议使用钩子,以便您可以在工作流的任何给定步骤添加新功能,而无需拆分应用程序。但是你应该添加哪些钩子?如果工作流程本身需要改变怎么办?

    许多软件开发人员使用Agile Software DevelopmentExtreme Programming 等方法或其他迭代方法。

    迭代开发的一个常见想法是,您不应该试图预测所有未来的变化。您预期的某些更改当然会发生,但很可能其中许多不会发生,因此您为预测可能更改所做的工作是浪费精力。

    所以你应该只写今天需要的软件。随着事情的变化,您将不得不重写其中的一些内容,但这是正常且不可避免的。而且很可能大部分都不会改变,所以设计越简单越好。假设是,通过仅关注当前需求,您可以充分减少整体工作量,从而实现净赢。

    当然,他们还说,当变化发生时,您应该优雅地响应变化,并通过经常与客户(或经理)沟通来减少浪费的时间。在这种情况下,模型和原型是有用的工具。 此外,不要害怕如实告诉您的经理,您需要多长时间才能重新设计软件以满足他的描述。您可以通过提出一些妥协来提供帮助。例如,他要求的单个功能通常是您需要重新架构的原因,否则更改将更加微小。因此,请公开谈论这一点,并进行对话,看看是否有另一种方法可以在没有太多工作的情况下解决同样的需求。这也应该符合他的利益,如果他能更快、更便宜地满足这种需求。

    不过,最终你可能会遇到一个完全没有理智的经理。在这种情况下,再多的谈判或改进你的方法也无济于事。不要为那些一直不尊重你、你的时间和你的工作成果的人工作。并且不要让他们在你身上走来走去,或者让你长时间工作而内疚。

    还可以阅读这篇幽默文章,它可能反映了您的情况:If Architects Had to Work Like Programmers

    【讨论】:

    • 谢谢比尔。总的来说,这就是我想要的。我同意我不应该试图预测所有未来的变化。我认为应用程序的问题是我没有预料到任何变化(主要或次要),因此使应用程序成为一堵砖墙。我将不得不研究这些开发方法。顺便说一句,谢谢你的笑声。可悲的是,这让我想起了我的客户。
    • +1。好帖子。 @Jesse:你可能会发现这篇值得一读:codinghorror.com/blog/2006/06/…
    【解决方案2】:

    钩子。

    使某些东西可扩展的最佳方法是使其具有许多清晰记录的插入点,用于附加代码。为适应新功能而对原始程序进行的修改越少越好。这个想法是在“扩展”、“附加组件”、“模块”等等的背后——让别人可以改进你的程序,而无需接触它的源代码。

    【讨论】:

    • 这其实是我在想的事情。我宁愿在可能的情况下不必更改原始程序,除非进行重大更改。我没有深入研究它,而且您不知道应用程序是如何构建的,您可能无法回答这个问题。但是,您知道如何将其添加到当前应用程序中吗?还是最好在考虑到钩子的情况下重写应用程序?
    【解决方案3】:

    由于 PHP 支持 OOP 并且我的学习从一开始就是 OOP,我建议您像手背一样学习面向对象的设计模式。另外,请多考虑“接口代码”。首先建立架构的方式与相关代码的可维护性有很大关系。您也许可以不理会应用程序并从头开始重新设计它,然后完全更换系统。这使得处理 300 个用户比一次更新小部分更容易。

    设计模式:http://en.wikipedia.org/wiki/Design_pattern

    【讨论】:

    • 应用程序是使用 OOP 构建的,但某些功能需要的不仅仅是设计模式,因为它们通常会改变整个应用程序的初衷。
    • 告诉他们“下一个版本会出现”
    【解决方案4】:

    根据需要,可以使用“插件”应用模型。

    【讨论】:

      【解决方案5】:

      你永远无法做出完全面向未来的东西。规格的制定是有原因的……以便他们可以遵守。虽然我会说如果客户想为每个主要版本付费,那是他们的特权。

      【讨论】:

      • 我同意这是规范的原因,客户一直在付款。但是,我觉得我本可以做其他项目的时间浪费了很多时间。
      【解决方案6】:

      尝试提前计划可能稍后添加的功能,并使用无需完全重写即可包含这些功能的设计。不过,在初始复杂性和以后轻松添加内容的能力之间显然需要权衡取舍。

      使事物模块化和松耦合也有帮助。如果您有一个具有相当明确的 API 的组件,则可以轻松地完全替换其实现,而无需接触太多或任何使用它的代码。

      【讨论】:

        【解决方案7】:

        几乎不可能对主要的新功能进行反编码。然而,有一些地方计划的灵活性总是一个好主意。首先,保持数据库接口抽象和表字段可扩展是有意义的。使用活动记录或表数据网关或类似方案通常很容易,有时简单的 $fieldnames[$table]=[a,b,c] 可能就足够了。

        当然,其次,尝试在钩子或插件上构建核心应用程序。不过,这同样只有助于扩展,而不是重大更改。

        如果您有现有用户并重新设计实时系统,那么实现数据库视图(甚至版本化?)、保留旧应用程序并在扩展存储方案上构建新版本可能会有所帮助。但实际上,这很难用通用的描述来评估。

        【讨论】:

          【解决方案8】:

          我想到了两个概念:“你不需要它”和“保持简单,愚蠢”。即,根据我的经验,为未来功能编码是创建糟糕代码的陷阱,然后无论如何未来都会不同。但也许这只是我。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-01-22
            • 1970-01-01
            相关资源
            最近更新 更多