打字猴:1.700456411e+09
1700456411
1700456412 (book.getPrice()/100.0)+“元”);
1700456413
1700456414 }
1700456415
1700456416 }
1700456417
1700456418 }
1700456419
1700456420 我们只修改了粗体部分,其他的部分没有任何改动,运行结果如下所示。
1700456421
1700456422 ––––书店买出去的书籍记录如下:–––––––
1700456423
1700456424 书籍名称:天龙八部 书籍作者:金庸 书籍价格:¥25.60元
1700456425
1700456426 书籍名称:巴黎圣母院 书籍作者:雨果 书籍价格:¥50.40元
1700456427
1700456428 书籍名称:悲惨世界 书籍作者:雨果 书籍价格:¥28.00元
1700456429
1700456430 书籍名称:金瓶梅 书籍作者:兰陵笑笑生 书籍价格:¥38.70元
1700456431
1700456432 OK,打折销售开发完成了。看到这里,各位可能有想法了:增加了一个OffNoveBook类后,你的业务逻辑还是修改了,你修改了static静态模块区域。这部分确实修改了,该部分属于高层次的模块,是由持久层产生的,在业务规则改变的情况下高层模块必须有部分改变以适应新业务,改变要尽量地少,防止变化风险的扩散。
1700456433
1700456434 注意 开闭原则对扩展开放,对修改关闭,并不意味着不做任何修改,低层模块的变更,必然要有高层模块进行耦合,否则就是一个孤立无意义的代码片段。
1700456435
1700456436 我们可以把变化归纳为以下三种类型:
1700456437
1700456438 ❑逻辑变化
1700456439
1700456440 只变化一个逻辑,而不涉及其他模块,比如原有的一个算法是a*b+c,现在需要修改为a*b*c,可以通过修改原有类中的方法的方式来完成,前提条件是所有依赖或关联类都按照相同的逻辑处理。
1700456441
1700456442 ❑子模块变化
1700456443
1700456444 一个模块变化,会对其他的模块产生影响,特别是一个低层次的模块变化必然引起高层模块的变化,因此在通过扩展完成变化时,高层次的模块修改是必然的,刚刚的书籍打折处理就是类似的处理模块,该部分的变化甚至会引起界面的变化。
1700456445
1700456446 ❑可见视图变化
1700456447
1700456448 可见视图是提供给客户使用的界面,如JSP程序、Swing界面等,该部分的变化一般会引起连锁反应(特别是在国内做项目,做欧美的外包项目一般不会影响太大)。如果仅仅是界面上按钮、文字的重新排布倒是简单,最司空见惯的是业务耦合变化,什么意思呢?一个展示数据的列表,按照原有的需求是6列,突然有一天要增加1列,而且这一列要跨N张表,处理M个逻辑才能展现出来,这样的变化是比较恐怖的,但还是可以通过扩展来完成变化,这就要看我们原有的设计是否灵活。
1700456449
1700456450 我们再来回顾一下书店销售书籍的程序,首先是我们有一个还算灵活的设计(不灵活是什么样子?BookStore中所有使用到IBook的地方全部修改为实现类,然后再扩展一个ComputerBook书籍,你就知道什么是不灵活了);然后有一个需求变化,我们通过扩展一个子类拥抱了变化;最后把子类投入运行环境中,新逻辑正式投产。通过分析,我们发现并没有修改原有的模块代码,IBook接口没有改变,NovelBook类没有改变,这属于已有的业务代码,我们保持了历史的纯洁性。放弃修改历史的想法吧,一个项目的基本路径应该是这样的:项目开发、重构、测试、投产、运维,其中的重构可以对原有的设计和代码进行修改,运维尽量减少对原有代码的修改,保持历史代码的纯洁性,提高系统的稳定性。
1700456451
1700456452
1700456453
1700456454
1700456455 设计模式之禅 [:1700453928]
1700456456 设计模式之禅 6.3 为什么要采用开闭原则
1700456457
1700456458 每个事物的诞生都有它存在的必要性,存在即合理,那开闭原则的存在也是合理的,为什么这么说呢?
1700456459
1700456460 首先,开闭原则是那么地著名,只要是做面向对象编程的,甭管是什么语言,Java也好,C++也好,或者是Smalltalk,在开发时都会提及开闭原则。
[ 上一页 ]  [ :1.700456411e+09 ]  [ 下一页 ]