软件设计的可维护性较低的原因:
A:过于僵硬。很难在一个软件系统里加入一个新的特性,由于设计上的缺陷,使得项目经理不敢轻易向系统加入新功能。
B:过于脆弱。
C:复用率低。一个程序员发现一段代码、函数、模块所做的事情可以在新的模块、或者新系统中使用的时候,会由于这些代码依赖于一大堆其他东西,很难将其分开。
D:粘度过高。
系统的可复用性
从最初的代码剪切复用到算法的复用、数据结构的复用。
设计的原则:
A:“开-闭”原则(OSP)
一个软件实体应当对扩展开放,对修改关闭。在设计一个模块的时候,应当使这个模块可以在不被修改的前提下被扩展。
优点:
1.通过扩展已有的软件系统,可以提供新的行为,以满足对软件的新需求,使变化中的软件系统有一定的适应性和灵活性。
2.已有的软件模块,特别是最重要的抽象层模块不能在修改,这就使变化中的软件系统有一定的稳定性和延续性。
实现:
A:解决问题的关键在于抽象化。可以给系统定义一个一劳永逸、不再更改的抽象设计,此设计允许有无穷无尽的行为在实现层被实现。可以给出一个或多个Java接口,规定出所有的具体类必须提供的方法的特征,来作为系统设计的抽象层。
对可变性的封装原则
找到一个系统的可变因素,将它封装起来这就意味着
A:一个可变性不应当散落在代码的很多角落里,而应当被封装到一个对象里面。而同一种可变性的不同表象意味着同一个继承等级结构中的具体子类。继承应当被看做封装变化的方法,而不应该被认为是从一般的对象生成特殊的对象的方法
B:一种可变性不应该和另一种可变性混合在一起。类图的继承结构一般都不会超过两层,不然就意味着将两种不同的可变性混合在一起。
总结
将“对可变性的封装原则”作为总的设计原则的话,系统的设计就会遵循“开-闭”原则。
B:里氏代换原则(LSP)
任何基类可以出现的地方,子类一定可以出现。里氏是对“开-闭”的补充。实现“开-闭”的关键步骤是抽象化,而基类与子类的继承关系就是抽象化的具体体现,所以里氏代换原则是对实现抽象化的具体步骤的规范。
C:依赖倒转原则(DIP)
要依赖抽象,不依赖于实现“开-闭”原则是目标,而依赖倒转是手段
D:接口隔离原则(ISP)
应当为客户端提供尽可能小的单独接口,而不要提供大的总接口。广义的迪米特法则要求尽可能限制通信的深度和宽度。接口隔离原则是限制通信的宽度。
E:组合\聚合复用原则(CARP)
要尽量使用合成/聚合,而不是继承关系达到复用的目的。合成/聚合复用原则是与里氏代换原则相辅相成,前者要求设计师首先考虑合成/聚合的关系,后者要求在使用继承关系时,必须确定这个关系是符合一定条件。
F:迪米特法则(LoD)
一个软件实体应当与尽可能少的其他实体发生相互作用。但一个系统需要扩展的时候,其中就有一些模块,他们修改的压力对于其他模块较大,最后的结果可能是需要修改或者不需要修改,但如果这些模块相对鼓励,那么他们就不会将修改的压力传递出去
策略模式对“开-闭”原则的支持
所谓的策略模式,对于一组算法,将每一个算法封装起来,使他们可以互换。策略模式就是从对可变性的封装原则出发,达到“开-闭”原则的范例。
例如:
在一个对图书销售折扣的计算问题中,分别有三个算法。在采用策略模式之前,设计师必须从“开-闭”原则出发,考察这个图书销售系统是否有可能在将来引进新的折扣算法。如果有那就将所有的折扣算法封装起来,因为他们是可变化的因素,必须在新算法出现时,很方便的将新算法插入系统中,而不必修改已有的系统。
而使用策略模式描述,这些不同的算法都是不同的策略角色。将每个算法用不同的命名去描述而为了使算法成为“即差即用”的对象,必须使这些算法能够相互特换。做到这一点的关键就是给这些对象定义出相同的接口,也就需要有一个抽象策略角色作为这些对象所组成的等级结构的超类型。
在图书销售折扣计算系统中,抽象策略角色有Java抽象类DiscountStrategy扮演
其他设计模式的支持
简单工厂
模式“开-闭”原则要求系统允许新的产品加入系统中,而无需对现有的代码进行修改。而每次新增加一个产品,都需要修改工厂的角色。但是产品的消费者就可以避免修改。
工厂方法模式
在工厂方法模式汇总,具体工厂类都要共同的接口,他们“生产”出很多的处于一个等级结构中的产品对象。使用这个设计的系统可以允许想系统加入新的产品类型,而不必修改已有的代码,只需要就如一个相应的新的具体类工厂就可以了。
抽象工厂模式
抽象工厂模式封装了产品对象家族的可变性,从而一方面可以使系统动态决定将哪一个产品族的产品实例化,另一方面可以在新的产品对象引进到已有的系统中时不必修改已有的系统
建造模式
建造模式封装了建造一个有内部结构的产品对象过程,因此,这样的系统是向产品内部表现的改变开放的。
桥梁模式
具体实现化类代表不同的实现逻辑,但是所有的具体实现化类又有共同的接口。新的实现逻辑可以通过创造新的具体实现化类加入到系统里面
门面模式
假设一个系统开始的时候与某一个子系统耦合在一起,后来又不得不换成另一个子系统,那么门面模式边可以发挥门面模式和适配器模式两种作用,将子系统仍然与本系统耦合。这样使用门面模式边可以改变子系统内部功能而不应该客户端。
调停者模式
调停者模式使用一个调停者对象协调各个同事的相互作用,这些同事对象不再发生直接的相互作用。一旦有新的同事对象添加到系统中的时候,这些已有的同事对象都不会受到影响,但是调停者对象本身却需要修改
访问者模式
访问中是的节点加入新的方法变得更容易,仅仅需要在一个新的访问者类中加入方法。但是访问中模式不能很好地处理增加新的节点的情况。访问中提供了倾斜的可扩展性设计:方法集合的可扩展性和类集合的不可扩展性。
迭代子模式
叠袋子模式将访问聚集元素的逻辑封装起来,并且使他独立于聚集对象的封装,使系统可以在无需修改消费迭代子的客户端的情况下,对聚集对象的内部结构进行功能扩展
留言与评论(共有 0 条评论) |