1、依赖倒置原则
高层模块不应该依赖于底层模块,两者都应该依赖于抽象。抽象不应该依赖于实现细节,实现细节应该依赖于抽象。
简而言之就是都应该只依赖于抽象。
因为抽象是对一类事物在共性上的一种提取,他是一个稳定的存在。依赖于它的模块和细节并不用担心他会发生变化,从而使得自身的模块和细节无法使用的情况。
2、开放封闭原则
对拓展开放,对修改关闭。
因为面向对象是基于一个稳定点来应对需求的变化的。很多模块都依赖了这个稳定点来运转的。如果对这个稳定点进行了修改,那会使得这个稳定点变得不太稳定。而这种修改,就很可能会使得依赖于它的模块无法正常使用。
因此,我们要关闭修改,以拓展的方式来应对需求的变化。
3、单一职责原则
一个类应该仅有一个引起它变化的原因。
当一个类的职责(需要处理的事情)太多的时候,会导致它和许多、类许多模块间产生依赖关系。造成一种紧耦合的情况,更坏的是,一旦这个类出现问题,可能第一时间无法得知到底是它的哪一种职责引发的。不利于代码的维护。
4、里氏替换原则
子类必须替换掉它的基类。
其实就是is-a关系的另外一种说法。相当于基类提供了方法和字段,在将子类替换成基类后,依然能够正常运转。假如无法正常运转,那说明他们之间不应该是is-a(继承)这种关系。
5、接口隔离原则
不应该强迫客户程序依赖它们不用的方法。
意思就是不要一味地public方法,应该将需要提供给客户端使用的接口给pulic出去,将没必要提供给用户的接口给private或protected隐藏起来。从而避免客户端之间紧耦合的一种情况。
6、合成复用原则
优先使用对象组合,而非类继承。
对于继承而言,实际上父类给子类暴露的东西是非常多的,它某种意义上破坏了类的封装性,从而使得子类与父类间高度耦合。
而对于组合来说,当前的类不需要了解组合的这个类的内部信息,两者间只需要制定好合适的接口就可以了。它的耦合度相对而言更低。
因此要尽量多用组合,少用继承。
7、封装变化点
要将变化的东西(对象)封装起来,使得设计人员在对这些变化的东西(对象)进行修改的时候,不会对外部产生不良的影响。
软件大师肯特.贝克曾说过:需求变化就如同一只调皮的小猫,我们应该把她关紧笼子里,让她在笼子里面调皮。
而封装变化点,实际上就是为这些变化的东西制造一个笼子,让它们在这里面变化。
8、面向接口编程
要针对接口编程,而不是针对实现编程。
意思就说,我们在使用许多对象共有的一个方法的时候,不建议(因为对于常用的数据结构,还是有必要声明成它的具体类型)声明这个对象的具体类型,而是应该声明成我们希望使用的这个方法所对应的接口。从而降低客户端和类设计端的耦合关系。
9、迪米特法则
只与你的直接朋友交谈,不跟“陌生人”说话。
意思就是说,如果我能够通过我的朋友来和陌生人进行交谈,那我就不要直接和陌生人交谈,从而降低系统间的耦合关系。
但这个法则没必要严格遵循。
软件大师马丁.福勒在他的《重构》中指出:随着受托类的特性(功能)越来越多,更多的转发函数会使人烦躁。服务类完全变成了一个中间人,此时就应该让客户直接调用受托类。(这个味道通常在人们狂热地遵循迪米特法则时悄然出现。我总觉得,如果这条法则当初叫做“偶尔有用的迪米特建议”,如今能少很多烦恼。)