前言

     继续上一篇,把余下的原则总结完。昨天一不小心看到一本好看的小说,看到了好几点,,感觉现在状态不太好,有错误望指正( ⊙ o ⊙ )。

 

4.依赖倒置原则 DIP(Dependence Inversion Principle)

     现在你是一名老总,发现部门业绩严重下滑,马上喊道:“把部门经理叫过来”,然后**部门经理就来挨批了。

     这就是依赖倒置原则。在人员频繁流动的情况下,老总如果总记着部门经理的名字岂不是很累,叫错了又很没面子?这个时候就有一个部门经理这个接口,老总说了,不管部门经理是谁,让他来见我,然后符合这个接口的人就来了,这里面的体现的关系是上层不依赖于下层(老总叫人不依赖于部门经理的名字),二者都依赖于抽象(部门经理职务),而且具体实现应该依赖于抽象(符合部门经理职务的人才叫部门经理)。

     查了查百度百科的例子,是这样说的:你是一个汽车自动驾驶系统产商,这时有两个车商联系你,他们的车都有开和停的方法。你需要声明一个自动驾驶类和两个对应的汽车类,并在自动驾驶类开和停的方法中判断是哪辆车的,调用那辆车的开或停方法。可是这个时候又多了几个车商呢?你又要多加几个汽车类,并在自动驾驶系统类中增加这几种车的判断。这时候高层模块(自动驾驶类)就依赖了底层模块(汽车类),导致这段代码脆弱且复用性差,那么应该怎么做呢?

     像上述说的,让他们依赖于抽象,即定义一个汽车接口,它具有开和停的方法。这时自动驾驶类只需要获取实现该接口的汽车对象,也就是这个类说:给我一辆车,我不管是什么车,需要开的时候我就调用这个车的开方法。而汽车类则实现这个接口,也具有开和停的方法。这样就方便了许多,如果听不懂请移步http://baike.baidu.com/linkurl=QkxUCJOU5465eGo6yrjyPqSVyJeDYWWeEckNngt4IENSTM34RCOh18Vb7oFR6_nXZ78554KmsarXaRTojlrTvughumQnwrC0pJ00t8VChi_2DOA5QV1OwM9e4yNq3Yd6ZFjUFEG5tjO883dTBfSvK查看具体代码实例。

     所以,依赖倒置原则,即要依赖于抽象,不要依赖于具体类。其原则是:1.高层模块不应该依赖于底层模块,二者都应该依赖于抽象。2.抽象不应该依赖于具体实现,具体实现应该依赖于抽象。

     高层应该去影响底层的实现,而不是底层影响高层。底层实现的接口应该由高层的需求决定,并由高层拥有使用,这就是所谓的倒置接口所有权。这个原则有些绕,你读懂了吗?

 

     ps:接口:通常以interface来声明,是抽象方法的集合(没有具体实现只有方法声明)。一个类继承接口,需要实现接口里所有的方法。

           抽象:接口或者抽象类,概念而非实例。

 

5.接口隔离原则 ISC(Interface Segregation Principle)

     接口隔离原则,即接口界的单一职责原则。

     比如你只是需要一个打扫地板接口,里面包含打扫的方法声明,别人却给了你一个干家务接口,里面包含了打扫,整理,清洁,擦拭等多个方法的声明,你继承了这个接口,不得不实现这些方法,哪怕根本用不到。就像被绑架一样,被迫使用这个臃肿的,被污染的接口。所以接口隔离原则,即不应该强迫客户依赖于他们不用的方法,即接口应尽量精简,更具有针对性,根据具体需求声明不同的接口,只为单一角色服务。

 

6.最少知识原则 LKP(Least Knowledge Principle)

      大家都知道类需要高内聚低耦合,所谓高内聚是指一个软件模块是由相关性很强的代码组成,只负责一项任务,也就是常说的单一责任原则。而最少知识原则则讨论的低耦合。

      对于低耦合,粗浅的理解是:一个完整的系统,模块与模块之间,尽可能的使其独立存在。也就是说,让每个模块,尽可能的独立完成某个特定的子功能。模块与模块之间的接口,尽量的少而简单。如果某两个模块间的关系比较复杂的话,最好首先考虑进一步的模块划分。这样有利于修改和组合。

      该原则即尽量减少对象之间的交流,也就是类之间的耦合性,这样当一个类需要修改时,就会尽可能少影响其他类,从而使系统具有更好的可维护性。

      哪些是需要交互的对象呢?《研磨设计模式》一书中提到:

  • 当前对象本身
  • 通过方法的参数传递进来的对象
  • 当前方法所创建的对象
  • 当前对象的实例变量所引用的对象
  • 方法内所创建或实例化的对象。

     该原则即尽量减少对象的依赖关系,或者说一个软件实体应当尽可能少的与其他实体发生相互作用。

 


7.其他原则 LKP(Least Knowledge Principle)

  • 合成复用原则:要尽量使用组合/聚合关系,少用继承(继承会增加类之间的耦合)。
  • 良性依赖原则:“不会在实际中造成危害的依赖关系,都是良性依赖”。即不要过度依赖设计原则和设计模式,上述仅供参考,要均衡好实际与设计之间的关系,避免过度设计,为了设计而设计却不合实际。
  • 面对接口编程:定义(规范,约束)与实现(名实分离的原则)的分离,如上述依赖倒置原则。
  • 一个类需要的数据应该隐藏在类的内部:使用private,protected,public等关键词,保护类内部的数据,只开放需要使用的方法。
  • 类之间应该零耦合,或者只有传导耦合:类之间要么没有关系,要么只是用另一个类的接口提供的操作。
  • 在水平方向上尽可能统一的分布系统功能:按照设计,顶层类应当统一的共享工作。在你的系统中不要创建全能类/对象。对名字包含Driver、Manager、System、Subsystem的类要特别多加小心。

 

总结

     类的约束:单一职责原则,开闭原则

     继承:里氏代换原则

     接口:接口隔离原则,依赖倒置原则

     类间:最少知识原则

     即类要高内聚低耦合,能扩展少修改,接口要职责单一,由高层模块决定。继承时不要覆盖父类方法,多使用接口和组合/聚合关系。

     理解即可,不需过度设计。如有兴趣可百度继续学习相关知识~。 下一章会讲解UML图的相关知识,你会发现很多地方都用到这种图,我们都需要懂它,或早或晚。