注:以下目的、好处、如何做仅个人方便理解用。
开闭原则
开闭原则:对拓展开放,对修改关闭。开闭原则就是指软件实体应尽量在不修改原有代码的情况下进行扩展。
目的:当软件系统需要面对新的需求时应该尽量保证系统的设计框架是稳定的。
好处:如果一个软件设计符合开闭原则,那么可以非常方便地对系统进行扩展,而且在扩展时无须修改现有代码,使得软件系统在拥有适应性和灵活性的同时具备较好的稳定性和延续性。
如何做:为了满足开闭原则,需要对系统进行抽象化设计。提供口、抽象类等,通过它们定义系统的抽象层,再通过具体类来进行扩展。
单一职责原则
单一职责原则:一个对象应该只包含单一的职责,并且该职责被完整地封装在一个类中。
目的:实现高内聚,低耦合
好处:类的复杂性降低,对于实现什么职责都有清晰明确的定义、变更引起的风险降低、可维护性提高、可读性提高。
如何做:想要很好地应用它需要设计人员具有较强的分析设计能力和相关实践经验。
依赖倒转原则
依赖倒转原则:高层模块(稳定)不应该依赖低层模块(变化),它们都应该依赖抽象(稳定)。抽象(稳定)不应该依赖于细节(变化),细节(变化)应该依赖于抽象(稳定)。简单来说,就是稳定不应该依赖于变化,变化应该依赖于稳定。
好处:程序将具有很好的灵活性、隔离变化。
如何做:传递参数时或在关联关系中尽量引用层次高的抽象层类,即使用接口和抽象类进行变量类型声明、参数类型声明、方法返回类型声明,以及数据类型的转换等,而不要用具体类来做这些事情。
里氏代换原则
里氏代换原则:所有引用基类的地方必须能透明地使用其子类的对象。里氏代换原则是实现开闭原则的重要方式之一,由于在使用基类对象的地方都可以使用子类对象,因此在程序中尽量使用基类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象。
目的:禁止不负责任地、泛滥地使用继承。(当父类的一些方法子类无法使用时就充分证明了这个子类不应继承该父类)
好处:使程序具有良好的拓展性。
如何做:在运用里氏代换原则时应该将父类设计为抽象类或者接口,让子类继承父类或实现父接口,并实现在父类中声明的方法,在运行时子类实例替换父类实例,可以很方便地扩展系统的功能,无须修改原有子类的代码,增加新的功能可以通过增加一个新的子类来实现。
接口隔离原则
接口隔离原则:客户端不应读依赖那些它不需要的接口(接口应该小而完备)。
目的:降低耦合,保持程序稳定。
好处:接口暴露出去的方法少,客户程序与接口之间的依赖就小,保持接口与程序的稳定就会更轻松。
如何做:接口中方法若仅自己使用就private,若子类使用就protect,当真正有必要暴露出去时才public。即仅仅提供客户端需要的行为,客户端不需要的行为则隐藏起来,应当为客户端提供尽可能小的单独的接口,而不要提供大的总接口。
合成复用原则
合成复用原则:优先使用对象组合,而不是通过继承来达到复用的目的。
原因:组合可以使系统更加灵活,降低类与类之间的耦合度,一个类的变化对其他类造成的影响相对较少。滥用继承会增加系统构建和维护的难度以及系统的复杂度,使用继承应严格遵守里氏转换原则。
好处:,降低类与类之间的耦合度
迪米特法则
迪米特法则:每一个软件单位对其他单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位.
迪米特法要求一个软件实体应当尽可能少地与其它实体发生相互作用如果一个系统符合迪米特法则,那么当其中的某一个模块发生修改时就会尽量少地影响其他模块,扩展会相对容易,这是对软件实体之间通信的限制
迪米特原则还有一个解释:Only talk to your immediate friends(只与直接朋友通信)。
什么叫直接朋友呢?每个对象都必然会与其他对象有耦合关系,两个对象之间的耦合就成为朋友关系,这种关系类型有很多,例如:组合,聚合,依赖等。朋友类也可以这样定义:出现在成员变量,方法的输入输出参数中的类,称为朋友类。
目的:封装变化点,对一个模块的改变几乎不影响其他模块。
好处:将系统中经常变化的部分和稳定的部分隔离,有助于增加复用性,并降低系统耦合度。
如何做:在设计系统时应该尽量减少对象之间的交互,如果两个对象之间不必彼此直接通信,那么这两个对象就不应当发生任何直接的相互作用,如果其中一个对象需要调用另一个对象的方法,可以通过“第三者”转发这个调用。