1700456444
一个模块变化,会对其他的模块产生影响,特别是一个低层次的模块变化必然引起高层模块的变化,因此在通过扩展完成变化时,高层次的模块修改是必然的,刚刚的书籍打折处理就是类似的处理模块,该部分的变化甚至会引起界面的变化。
1700456445
1700456446
❑可见视图变化
1700456447
1700456448
可见视图是提供给客户使用的界面,如JSP程序、Swing界面等,该部分的变化一般会引起连锁反应(特别是在国内做项目,做欧美的外包项目一般不会影响太大)。如果仅仅是界面上按钮、文字的重新排布倒是简单,最司空见惯的是业务耦合变化,什么意思呢?一个展示数据的列表,按照原有的需求是6列,突然有一天要增加1列,而且这一列要跨N张表,处理M个逻辑才能展现出来,这样的变化是比较恐怖的,但还是可以通过扩展来完成变化,这就要看我们原有的设计是否灵活。
1700456449
1700456450
我们再来回顾一下书店销售书籍的程序,首先是我们有一个还算灵活的设计(不灵活是什么样子?BookStore中所有使用到IBook的地方全部修改为实现类,然后再扩展一个ComputerBook书籍,你就知道什么是不灵活了);然后有一个需求变化,我们通过扩展一个子类拥抱了变化;最后把子类投入运行环境中,新逻辑正式投产。通过分析,我们发现并没有修改原有的模块代码,IBook接口没有改变,NovelBook类没有改变,这属于已有的业务代码,我们保持了历史的纯洁性。放弃修改历史的想法吧,一个项目的基本路径应该是这样的:项目开发、重构、测试、投产、运维,其中的重构可以对原有的设计和代码进行修改,运维尽量减少对原有代码的修改,保持历史代码的纯洁性,提高系统的稳定性。
1700456451
1700456452
1700456453
1700456454
1700456456
设计模式之禅 6.3 为什么要采用开闭原则
1700456457
1700456458
每个事物的诞生都有它存在的必要性,存在即合理,那开闭原则的存在也是合理的,为什么这么说呢?
1700456459
1700456460
首先,开闭原则是那么地著名,只要是做面向对象编程的,甭管是什么语言,Java也好,C++也好,或者是Smalltalk,在开发时都会提及开闭原则。
1700456461
1700456462
其次,开闭原则是最基础的一个原则,前五章节介绍的原则都是开闭原则的具体形态,也就是说前五个原则就是指导设计的工具和方法,而开闭原则才是其精神领袖。换一个角度来理解,依照Java语言的称谓,开闭原则是抽象类,其他五大原则是具体的实现类,开闭原则在面向对象设计领域中的地位就类似于牛顿第一定律在力学、勾股定律在几何学、质能方程在狭义相对论中的地位,其地位无人能及。
1700456463
1700456464
最后,开闭原则是非常重要的,可通过以下几个方面来理解其重要性。
1700456465
1700456466
1.开闭原则对测试的影响
1700456467
1700456468
所有已经投产的代码都是有意义的,并且都受系统规则的约束,这样的代码都要经过“千锤百炼”的测试过程,不仅保证逻辑是正确的,还要保证苛刻条件(高压力、异常、错误)下不产生“有毒代码”(Poisonous Code),因此有变化提出时,我们就需要考虑一下,原有的健壮代码是否可以不修改,仅仅通过扩展实现变化呢?否则,就需要把原有的测试过程回笼一遍,需要进行单元测试、功能测试、集成测试甚至是验收测试,现在虽然在大力提倡自动化测试工具,但是仍然代替不了人工的测试工作。
1700456469
1700456470
以上面提到的书店售书为例,IBook接口写完了,实现类NovelBook也写好了,我们需要写一个测试类进行测试,测试类如代码清单6-6所示。
1700456471
1700456472
代码清单6-6 小说类的单元测试
1700456473
1700456474
public class NovelBookTest extends TestCase{
1700456475
1700456476
private String name=“平凡的世界”;
1700456477
1700456478
private int price=6000;
1700456479
1700456480
private String author=“路遥”;
1700456481
1700456482
private IBook novelBook=new NovelBook(name,price,author);
1700456483
1700456484
//测试getPrice方法
1700456485
1700456486
public void testGetPrice(){
1700456487
1700456488
//原价销售,根据输入和输出的值是否相等进行断言
1700456489
1700456490
super.assertEquals(this.price,this.novelBook.getPrice());
1700456491
1700456492
}
1700456493
[
上一页 ]
[ :1.700456444e+09 ]
[
下一页 ]