《程序员修炼之道:从小工到专家》第七章:在项目开始之前

一、需求之坑

完美,不是在没什么需要增加,而是在没什么需要去掉时达到的。

需求很少存在于表面上。通常,它们深深埋藏在层层假定、误解和政治手段的下面。

不要搜集需求——挖掘它们

挖掘需求

挖掘商业本质,将需求作为一般陈述,具体的要求作为元数据,从而进行良好的分解。

找出用户为何要做特定事情的原因,而不只是他们目前要做这件事的方式,这很重要。到最后,你的开发必须解决他们的商业问题,而不只是满足他们陈述的需求。用文档记载需求背后的原因将在每天进行实现决策时给你的团队带来无价的信息。

有一种能深入了解用户需求、却未得到足够利用的技术:成为用户。

与用户一同工作,以像用户一样思考

建立需求文档

描述系统的特定用法——不是根据用户界面,而是以一种更加抽象的方式。

用例图

可以用UML活动图捕捉工作流,而且有时要为手边的事务建模,概念层类图很有用。用例可以含有指向其他用例的超链接,它们也可以相互嵌套。

规定过度

制作需求文档的一大危险是太过具体。好的需求文档会保持抽象。在涉及需求的地方,最简单的、最能够准确反映商业需要的陈述是最好的。

需求不是架构。需求不是设计,也不是用户界面。需求是需要。

看远些

抽象比细节活得更长久

再抹一层薄薄的薄荷

许多项目的失败都被归咎于项目范围的增大——也称为特性膨胀、蔓延特性论、或是需求蔓延。这是“石头汤与煮青蛙”中的煮青蛙综合症的一个表征。

管理需求增长的关键是向项目出资人指出每项新特性对项目进度的影响。

我们很容易被吸进“只是再增加一个特性”的大漩涡,但通过追踪需求,你可以更清楚地看到,“只是在增加一个特性”,其实已经是本月新增的第15个新特性。

维护词汇表

使用项目词汇表

定义项目中使用的专用术语和词汇的地方,以确保一致性,避免歧义。

二、解开不可能解开的谜题

弗里吉亚国王戈尔迪斯曾经系过一个没有人能解开的结。据说能解开戈尔迪斯结谜题的人将会统治整个亚洲。亚历山大大帝来了,用剑劈开了这个结。只是对要求做了小小的不同的解释,就是这样。他后来的确统治了亚洲大部分。

整个故事告诉我们,解决问题的关键往往不在问题本身,而是其他地方。

自由度

不要在盒子外思考,要找到盒子

解开谜题的关键在于确定给你加的各种约束,帮确定你确实拥有的自由度,因为在其中你将找到解决方案。

你必须挑战任何先入之见,并评估他们是否是真实的,必须遵守的约束。

在面对棘手的问题时列出所有的在你面前的可能途径。不要排除任何东西,不管它听起来有多无用或愚蠢。

对你的约束进行分类并划分优先级,先确定最为严格的约束,然后再在其中考虑其余的约束。

一定有更容易的方法!

有时你会发现自己在处理的问题似乎比你以为的要难得多。感觉上好像是你走错了路——一定有比这更容易的方法!这正是你回退一步,问问自己以下问题的时候:

  • 有更容易的方法吗?
  • 你是在设计解决真正的问题,还是被外围的技术问题转移了注意力?
  • 这件事情为什么是一个问题?
  • 是什么使它如此难以解决?
  • 它必须以这种方式完成吗?
  • 它真的必须完成吗?

很多时候,当你设法回答这些问题的时候,你会有让自己吃惊的发现。很多时候,对需求的重新诠释会让整个问题全都消失——正如戈尔迪斯结。

你所需要的只是真正的约束、令人误解的约束,以及区分它们的智慧。

三、等你准备好

倾听反复出现的疑虑——等你准备好再开始

是良好的判断,还是拖延

每个人都害怕空白的纸页,启动新项目可能会是让人心力交瘁的经验。我们许多人更愿意延缓做出最初的启动承诺。那么,你怎样才能知道,你什么时候是拖延,而不是负责任地等待所有工作的准备就绪?

开始构建原型。

典型的情况下,会有两种结果:

一种是开始后不久你就可能觉得自己是在浪费时间。这种厌烦可能很好的表明你最初的勉强只是为了推迟启动。放弃原型,回到真正的开发中。

另一种是随着原型取得进展,你可能会在某个时刻得到启示,突然意识到某个基本前提错了。你的直觉是正确的,你为你自己和团队节省了可观的、本来会浪费的努力。

从政治策略的角度说,去构建原型也许比简单的宣布“我不该启动”,并开始玩单人纸牌游戏更能让人接受。

四、规范陷进

编写程序规范就是把需求归约到程序员能够接管的程度的过程。这是一个交流活动,旨在解释并澄清系统的需求,比如消除主要的歧义。除了与最初的开发者交谈以外,规范还是留给未来进行代码维护和增强的几批程序员的记录。规范也是与用户的约定。

编写规范是一项重要职责。

问题是很多设计者发现很难停下来。这是一个错误:

首先,认为规范将捕捉系统或其需求的每一处细节和细微差别,这很幼稚。

其次,语言自身的表达能力存在着问题。对有些事情,“做”胜于“描述”。

最后,还有“紧身衣效应”,没有给编码者留下任何解释余地的设计剥夺了他们发挥技巧和艺术才能的机会。

作为一个注重实效的程序员,应该把需求搜集、设计、以及实现视为同一个过程——交付高质量系统——的不同方面。

我们并不是反对生成规范,相反,有时需要及其详细的规范。只是要知道,随着规范的越来越详细,你得到的回报会递减,甚至会是负回报。

五、圆圈与箭头

不要做形式方法的奴隶

形式方法有一些严重缺点:

  • 大多数形式方法结合图和某些文字来捕捉需求,而这往往只是设计者的理解,于最终用户没有意义
  • 形式方法似乎鼓励专门化,从而带来糟糕的交流和工作的浪费
  • 我们喜欢编写有适应能力的动态系统,使用元数据让我们在运行时改变应用的特征,而形式方法做不到这一点

形式方法能成功吗?

绝不要低估使用新方法和新工具的代价。要做好准备,把使用这些新技术的第一个项目当做一种学习经验。

我们应否使用形式方法?

绝对应该。

但要始终记住形式开发方法只是工具箱里的又一种工具。如果在仔细分析之后,你觉得需要使用形式方法,那就使用它,但要记住谁是主人,不能成为方法学的奴隶。

注重实效的程序员会批判地看待方法学,并从中提取精华,融合成每个月都在变得更好的一套工作习惯。

昂贵的工具不一定能制作出更好的设计

学院君

学院君 has written 554 articles

资深PHP工程师,Laravel学院院长