本篇旨在将设计模式中涉及的几个常用的设计原则进行一并的讲解,其中包含依赖倒置原则、开放-封闭原则、好莱坞原则、最少知识原则(迪米特法则)、单一职责原则其他的后续补充
依赖倒置原则
即高层组件不应该依赖于底层组件,两者都要依赖抽象,不要依赖具体类
抽象不应该依赖细节,细节应该依赖抽象,针对接口编程,不要针对实现编程
比如工厂方法就遵循了这个原则,一般工厂方法的工厂都会继承自一个抽象工厂,继承之后再在工厂内部实现自己的功能,但是具体工厂之间不会互相继承,因为一旦继承,彼此之间就会互相影响,一个父类的改变就会影响到子类
比如电脑中的各个配件,发展的趋势都是分离化的,CPU,内存条,显卡,这些比较复杂的东西都相互分离,彼此之间只留下接口,CPU和主板,内存条,显卡彼此之间互相不依赖
针对实现编程:主板是针对某一个品牌的CPU设计的,针对某种品牌CPU的特性做了特殊处理,当CPU坏掉了,换另一个品牌的CPU就不兼容,需要修改主板
针对接口编程:主板是针对CPU的抽象类进行设计的,而不关心具体的CPU类的特性,只要插上来的是CPU不是马桶圈,无论是什么品牌什么形状的,主板认接口不认细节,都能跑,主板的一切和CPU内部无关
如同上面的例子,主板和CPU都是具体的东西,所以彼此不依赖,而是依赖一个抽象的东西,CPU依赖的是抽象的主板,也就是所有主板的共性,而主板依赖的也是所有CPU的共性,即细节依赖抽象,如果主板和CPU只能一一配对,不兼容的,就是抽象依赖细节了
也就是说,设计依赖关系的时候,要考虑好兼容,被依赖的对象应该是一种共性,即随着需求变动一般不太会改变的东西,如果被依赖的东西经常会改变,那么依赖它的东西就需要经常因为被依赖物的改变而改变,引起Bug
存疑:超类是否违背依赖倒置原则,或者说,超类就是抽象?
开放封闭原则
代码对外开放扩展,关闭修改
开放扩展是为了更好地被使用,而关闭修改则是为了减少新改动对旧代码产生bug
观察者模式就是一种扩展,通过注册订阅来扩展主体,而不是每次订阅都要修改主体
装饰者模式也是一种扩展,通过装饰来给固有对象动态添加额外的功能效果,而不用修改固有代码
并不是所有模块都需要开放-封闭原则,只是在会频繁发生改变的地方遵循这个原则,开放-封闭会导致代码复杂度增加,每一个地方都使用开放-封闭原则是一种浪费
好莱坞原则
不要给我们打电话,我们会给你打电话
低层不应该调用高层,或者循环调用,应该由高层去调用低层
最少知识原则(迪米特法则)
尽量减少和一个模块直接发生交流的事物,如果两个模块需要沟通,则尽量采用第三方传递消息的方式
比如发生火灾了,直接一个119拨打出去,告诉地址就会有救火队过来救火,但是如果没有119的电话,想要救火就得一一联系救火队里的成员,成员电话发生改变还会造成打不通,119就是消防局对外的统一接口,需要救火打119即可,至于消防局内部如何调配,派哪个消防员过来救火,拨打电话的人可以不关注
类似的120,110也是如此
外观模式、代理模式就是利用了最少姿势原则,对外展露统合后的接口,减少外部对复杂接口的调用,从而减少了耦合,只是外观模式没有保护作用,外界依然可以访问内部细节,就像手机设置了情景模式之后依然可以自己微调细节,这就是外观模式,而代理模式更像是电风扇开小中大三档,不会允许使用者自己去细调速度
单一职责原则
一个类应该只有一个引起变化的原因
即高内聚,低耦合中的高内聚,类的功能要单一,降低这个类未来的变化几率,因为变化就意味着容易出错,当一个类负责了A和B两个功能,如果改变了A,与之在同一个类中的功能B也会受到影响,可能会出错,如果A和B分离开来,那么改变功能A的时候,B就不会受到影响