第4章 “开-闭”原则(Open-Closed Principle/OCP)
一个软件实体应当对扩展开放,对修改关闭。
Software entities should be open for extension,but closed for modification.
这个原则说的是,在设计一个模块的时候,应当使这个模块可以在不被修改的前提下被扩展。
满足“开-闭”原则的设计可以给一个软件系统两个无可比拟的优越性:
l 通过扩展已有的软件系统,可以提供新的行为,以满足对软件的新需求,使变化中的软件系统有一定的适应性和灵活性。
l 已有的软件模块,特别是最重要的抽象层模块不能再修改,这就使变化中的软件系统有一定的稳定性和延续性。
里氏代换原则:任何基类可以出现的地方,子类一定可以出现。
依赖倒转原则:要依赖于抽象,不要依赖于实现。
合成/聚合复用原则:要尽量使用合成/聚合,而不是继承关系达到复用的目的。
迪米特法则:一个软件实体应当与尽可能少的其他实体发生相互作用。
接口隔离原则:应当为客户端提供尽可能小的单独的接口,而不要提供大的总接口。
策略模式:如果有一组算法,那么就将每一个算法封装起来,使得它们可以互换。
第5章 专题:JAVA语言的接口
在Java语言中,Java接口可以定义public的常量,可以有public、static、final的属性。
在Java编译器检查方法的置换(Overrride)时,会进一步检查两个方法的返还类型和抛出的异常是否相同。
接口代表一个角色(role),实现这个接口的类便是扮演这个角色的演员。一个角色可以由不同的演员来演,而不同的演员之间除了扮演一个共同的角色之外,并不要求有任何其他的共同之处。
应当使用Java接口和抽象Java类而不是具体类进行变量的类型声明、参量的类型声明、方法的返还类型声明,以及数据类型的转换等。当然,一个更好的做法是仅仅使用Java接口,而不要使用抽象Java类来做到上面这些。
Java接口的常见用法:
单方法接口:一个单方法接口只含有一个方法。如:Runnable接口
标识接口:没有任何方法和属性的接口。如:java.io.Serializable、java.rmi.Remote
常量接口:用java接口来声明一些常量,然后由实现这个接口的类使用这些常量。(这种方法是错误的)
第6章 专题:抽象类
具体类不是用来继承的。只要有可能,不要从具体类继承。
在一个以继承关系形成的等级结构里面,树叶节点均应当是具体类,而树枝节点均应当是抽象类(或者Java接口)。这样的设计是所有的Java设计师都应当努力做到的。
在一个从抽象类到多个具体类的继承关系中,共同的代码应当尽量移动到抽象类里,可以提高代码的复用率。
抽象类应当拥有尽可能少的数据。
只有当以下的Coad条件全部被满足时,才应当使用继承关系:
(1) 子类是超类的一个特殊种类,而不是超类的一个角色,也就是要区分“Has-A”与“Is-A”两种关系的不同。
(2) 永远不会出现需要将子类换成另一个类的子类的情况。
(3) 子类具有扩展超类的责任,而不是具有置换掉(Override)或注销掉(Nullify)超类的责任。
只有在分类学角度上有意义里,才可以使用继承,不要从工具类继承。