1.开闭原则
在设计一个模块时,应当使这个模块可以在不被修改的前提下被扩展。开闭原则从另外一个角度讲述,就是“对可变性的封装原则”,即找到一个系统的可变因素,将之封装起来。这意味着两点:
可变性应当被封装到一个对象里面。继承应当被看做封装变化的方法,而不是从一般对象生成特殊对象的方法。
一种可变性不应当与另一种可变性混合在一起,实践上,通常类图的继承结构不会超过两层。
“将条件转移语句改写成为多态性”,将一个进行多次条件转移的商业逻辑封装到不同的具体子类。
如果一个条件转移语句没有涉及重要的商务逻辑,或者不会随着时间的变化而变化,也不意味着任何的可扩展性,那么它就没有涉及任何有意义的可变化。这就没必要转成多态性。
2.里氏代换原则
一个软件实体如果使用的是一个基类的话,那么一定适用于其子类,而且它根本不能察觉出基类对象和子类对象的区别。
3.依赖倒转原则
有两种表述
要依赖于抽象,不要依赖于具体。传统过程性系统设计方法倾向于使高层次的模块依赖于低层次的模块,抽象层次依赖于具体层次。倒转,就是要把这种错误依赖关系倒转过来。
抽象层次包含应用系统的商务逻辑和宏观的,对整个系统来说重要的战略性决定,是必然性的体现。
只要一个被引用的对象存在抽象类型,就应当在任何引用此对象的地方使用抽象类型,包括参数的类型声明、方法返回类型的声明、属性变量的类型声明等。
多个工厂模式,解决了创建过程中的依赖倒转问题。
任何方法无法回避java语言要求的new关键字和直接调用具体类的构造子的做法。简单工厂模式将这个违反“开-闭”原则以及依赖倒转原则的做法封装到了一个类里面,而工厂模式将这个违反原则的做法推迟到了具体工厂角色。
缺省适配模式
抽象类具有提供缺省实现的优点,java接口具有其他优点,所以缺省适配模式联合使用两者。声明类型的工作仍然由java接口承担,同时给出java抽象类,为接口提供一个缺省实现。如果需要加一个方法,那只用向抽象类加一个具体实现就可以。javaAPI很多使用这种模式,命名规范为Abstract+接口名,如AbstractCollection。
有些具体类非常稳定,不会发生变化,这时不需要用一个抽象类型。
4.接口隔离原则
使用多个专门的接口,比使用单一接口要好。换言之,一个类对另一个类的依赖性,应当建立在最小的接口上。
准确而恰当地划分角色以及角色所对应的接口,是面向对象设计的一个重要组成部分。
5.组合/聚合复用原则
要尽量使用关联,而不是继承。
组合是值的聚合,聚合是引用的聚合。
6.迪米特法则
朋友的条件
缺点:遵循类之间的迪米特法则,会让系统的局部设计简化,每个局部都不会和远距离的对象有直接的关联,但会造成系统的不同模块间的通信效率降低,使系统的不同模块间不容易协调。
为了克服狭义的迪米特法则的缺点,可以使用依赖倒转原则,引入一个抽象的类型引用“抽象陌生人”对象,使“某人”依赖于“抽象陌生人’。换言之,就是将“抽象陌生人”变成朋友。
广义迪米特法则在类的设计上的体现
广义迪米特法则在代码上的体现
7.系统可扩展性、灵活性、可插入性和设计原则的关系
系统的可扩展性由开-闭原则,里氏代换原则,依赖倒转原则和组合/聚合复用原则所保证的。
系统灵活性由开-闭原则,迪米特法则,接口隔离原则所保证的。
系统可插入性由开-闭原则,里氏代换原则,依赖倒转原则和组合/聚合复用原则所保证的。
8.小结
设计原则对系统设计提供指导,但并不能僵硬的理解原则。需要全面的了解原则制定的原因,原则的优点和缺点,结合实际,合理利用原则。只要有足够的理由,在一些场合甚至可以做一些“反原则”的设计。
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。