2

背景

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

问题

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

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

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

4

8 回答 8

5

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

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

许多软件开发人员使用敏捷软件开发极限编程或其他迭代方法等方法。

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

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

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

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

另请阅读这篇幽默文章,它可能反映了您的情况:如果建筑师必须像程序员一样工作

于 2010-07-28T20:25:19.983 回答
2

挂钩。

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

于 2010-07-28T19:53:31.980 回答
1

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

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

于 2010-07-28T19:55:21.183 回答
1

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

于 2010-07-28T19:55:38.407 回答
0

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

于 2010-07-28T19:54:05.367 回答
0

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

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

于 2010-07-28T19:59:06.900 回答
0

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

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

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

于 2010-07-28T20:02:15.270 回答
0

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

于 2010-07-28T20:12:33.893 回答