案例:吉他搜索
Guitar Inventory GuitarSpec
需求变化:增加吉他弦数特性
原始程序需要的变化:
1.修改GuitarSpec,构造,成员,getter
2.修改Guitar,构造,因为改类直接接收吉他特性参数,构造吉对象。
3.修改Inventory,搜索方法,因为该类直接使用吉他特性来进行匹配。
另一种设计:
1.修改Guitar的构造器,让其接收GuitarSpec对象,而不是具体的吉他特性参数。
2.修改Inventory的搜索方法,其中委托GuitarSpec提供的matches()方法进行匹配。
另一种设计程序需要的变化:
1.在GuitarSpec中,增加弦数成员,修改构造,getter,matches()方法。
优点:吉他特性的变化的锚点被集中到了GuitarSpec中,虽然锚点的数量并没有改变,但是我们的程序因为锚点更集中,让我们找到所有的锚点更容易,程序更容易维护。
可以使用锚点这个词语:
增加吉他特性(如弦数)必须找到程序中所有吉他特性产生的锚点,进行改变。这是必要的操作。
原始程序吉他特性的锚点分布在了GuitarSpec,Guitar,Inventory中,当重新设计后,吉他特性的锚点被集中到了GuitarSpec中,范围更小了。锚点数量越多越分散我们的程序就越难以修改。锚点数量越少越集中我们的程序就越容易修改和维护。
第2个优点:吉他特性的比较功能被抽取了出来,更容易复用。
好的设计:
1.集中程序中吉他特性相关的锚点到GuitarSpec类中。锚点数量越少,越集中,找到全部锚点并进行修改的工作就越容易,即程序可维护。
2.抽取matches()方法,并将该方法移动到GuitarSpec类中,而在Inventory类的search方法中使用委托。本质上是1中的具体实现。这样让类间的职责与分工更加明确。matches()方法更易被重用。
伟大软件的三个步骤:
1.确认你的软件做客户要它做的事
2.运用基本的面向对象原则增加软件的灵活性
3.努力实现可维护可重用的设计
业务阶段:
需求:是一个业务目标
用例:是真实环境中用户使用系统实现一个业务目标的详细步骤。
用例焦点:客户的目标
用例关键:系统解决,用系统解决可能存在的妨碍用户实现业务目标的问题。
用例名词:
场景:用例的一个执行路径。(所有的执行路径都需要被测试)
可选路径:可选路径是可能发生的额外情况
分支路径:将会执行多条分支路径中的一个
一个用例三个部分:1.清楚的价值 2.起点与终点 3.外部启动者
需求和用例
1.创建需求列表:用户提出自己原始需求(简陋的,不全面的需求),客户要用系统做的事情。
2.用例:为每个特定的业务目标使用单独的用例,更好的理解这个业务目标。(预料事情会出错,即考虑用户使用系统实现业务目标时可能发生的问题,系统没有考虑到,但如果出现这种问题,会妨碍用户完成业务目标。)
3.改进需求列表:根据用例,用例帮助我们发现一些问题,因此我们需要改进原始的需求列表。
比对需求列表和用例的步骤,如果用例的某个步骤没有找到对应的需求,则我们需要增加新的需求到需求列表中。
4.变化发生,需求列表新增需求:
5.改进用例
6.改进需求列表
...
风险规避:
用例:为了完成一个特定的业务目标的一系列步骤的描述。这些步骤中系统应该做什么。
场景:用例的一个执行路径。(所有的执行路径都需要被测试)
可选路径:可选路径是可能发生的额外情况
分支路径:将会执行多条分支路径中的一个
用例把焦点放在完成一个特定目标上。
用例包含的是系统应该做什么而不是怎么做。
一个用例三个部分:1.清楚的价值 2.起点与终点 3.外部启动者