1. “开-闭”原则(OCP)
一个软件实体应当对扩展开放,对修改关闭。
Software entities should be open for extension, but closed for modification.
2. 里氏代换原则(LSP)
任何基类出现的地方,子类一定可以出现。
3. 依赖倒转原则
要依赖于抽象,不要依赖于实现。即:要针对接口编程,不要针对实现编程。
在很多情况下,一个Java程序需要引用一个对象,这个时候,如果这个对象有一个抽象类型的话,应当使用这个抽象类型作为变量的静态类型。这就是针对接口编程的含义。
4. 合成/聚合复用原则
要尽量使用合成/聚合,而不是继承关系达到复用的目的。
合成/聚合复用的好处:
- 新对象存取成分对象的唯一方法是通过成分对象的接口。
- 这种复用是黑箱复用,成分对象的内部细节是新对象所看不见的。
- 这种复用支持封装。
- 这种复用所需的依赖较少。
- 每一个新的类可以将焦点集中在一个任务上。
- 这种复用可以在运行时刻动态进行,新对象可以动态的引用与成分对象类型相同的对象。
合成/聚合复用的缺点:
- 有较多的对象需要管理。
继承复用的好处:
- 新的实现较为容易,因为超类的大部分功能可以通过继承关系自动进入子类。
- 修改或扩展继承而来的实现较为容易。
继承复用的缺点:
- 继承复用破坏封装,因为继承将超类的实现细节暴露给子类。由于超类的内部细节常常是对子类透明的,因此这种复用是透明的的复用,又称“白箱”复用。
- 如果超类发生改变,那么子类的实现也不得不发生改变。
- 从超类继承而来的实现是静态的,不可能在运行时间内发生改变,因此没有足够的灵活性。
5.迪米特法则
一个软件实体应当与尽可能少的其他实体发生相互作用。
6.接口隔离原则
应当为客户提供尽可能小的单独的接口,而不是提供大的总接口。
7. Others.
1) 应当使用Java接口与抽象类而不是具体类进行变量的类型声明、参量的类型声明、方法的返还类型声明,以及数据类型的转换等。更好的做法是只使用Java接口。
2) 由于抽象类不能实例化,因此一个设计师设计一个抽象类,一定是用来继承的。 具体类不是用来继承的, 只要有可能,不要从具体类继承。
3) 在一个以继承关系形成的等级结构里面,树叶结点均应当是具体类,而树枝节点均应当是抽象类。
4) 抽象类应当拥有尽可能多的共同代码。
5) 抽象类应当拥有尽可能少的数据。
Misc:
关联(Association)关系
关联关系是类与类之间的联接,它使一个类知道另一个类的属性和方法。 在Java语言里,关联关系是使用实例变量实现的。
聚合(Aggregation)关系
聚合关系是关联关系的一种,是强的关联关系。聚合是整体和个体之间的关系。 与关联关系一样,聚合关系也是通过实例变量实现的。
合成(Composition)关系
合成关系是关联关系的一种,是比聚合关系强的关系。它要求普通的聚合关系中代表整体的对象负责代表部分的对象的生命同期,合成关系是不能共享的。
依赖(Dependency)关系
依赖也是类与类之间的连接,依赖总是单向的。依赖关系表示一个类依赖于另一个类的定义。一般而言,依赖关系在Java语言中体现局域变量、方法的参量, 以及对静态方法的调用。换言之,一个类A 的某一个局域变量的类型是另一个类B,那么类A就依赖于类B。如果一个方法的参量是另一类B的实例,那么这个方法所在的类A依赖于类B。如果一个类A调用另一个类B的静态方法,那么类A依赖于类B。