架构师训练营 第二周 学习总结
面向对象设计原则
面向对象设计原则也被称为 SOLID 原则 , 根据 维基百科 对 SOLID 的介绍, 它最初由 Robert C.Martin 于 2000 年的 论文 中提出。
所以网上很多人说 GoF 23 种设计模式遵循了 SOLID 原则感觉有些不妥, 因为 GoF 在 1994 年提出, SOLID 在 2000 年提出。
所以 GoF 提出的时候还没有 SOLID 所以就没有遵循 SOLID 一说,并且 GoF 有些模式是违背了 SOLID 原则的。
面向对象设计原则主要包括:
单一职责原则 (Single Responsibility Principe 简称 SRP)
开闭原则 (Open-Closed Principle 简称 OCP)
里氏替换原则 (Liskov Substitution Principle 简称 LSP)
接口隔离原则 (Interface Segregation Principle 简称 ISP)
依赖倒置原则 (Dependency Inversion Principe 简称 DIP)
所以面向对象设计原则又称 SOLID 原则, 由上面设计原则首字母组成。
除了 SOLID 原则, 还有一个 迪米特法则 (Law of Demeter 简称 LoD).
一、单一职责原则
定义:就一个类而言,应该仅有一个引起它变化的原因。
理解:当一个类所负责的事情足够单一的时候,不仅可以能够专注的把所负责事情做好。如果一个类负责多个职责,必然会导致各个职责相互之前存在耦合。这就不符合我们高内聚、低耦合的要求。导致的问题就是,这个类的代码在不断的增加,牵着着各种功能点的代码。如果某个功能需要修改时,不得不考虑是否对其他的功能带来影响。
二、开闭原则
定义:对于扩展是开放的,对于修改是封闭的;
理解:意思就是可以任意的往外边扩展,但是不能对写好的代码修改,怎么达到这个要求呢?写接口。执行的方法写成接口,这样如果我们要扩展不同的实现,那就可以扩展新的实现了原来接口的类,然后丢进去就可以啦;
三、里氏替换原则 LSP
定义:所有应用其基类的地方,必须都能透明的使用其子类的对象;
核心原理:抽象、继承、多态
理解:当我要一个人干一种活的时候,发现有一类人都要干这种活,比如吃饭。那么,我就可以把这一类人抽象出来,同样干“吃饭”这种活,不过很明显,每个人都会有每个人的吃放。所以吃饭这个活也是抽象的,继承的实现体具体去干自己的活。当然,加入我是食堂的,我喊一声可以吃放了。然后不同的人(实现体)就跑进食堂,纷纷吃自己的饭啦!
四、依赖倒置原则 DIP
定义:模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或者抽象类产生的;
理解:假如我现在需要租个房子,然后我把身边的朋友叫过来,说给我帮忙找个房子。然后朋友们就去找了。还有一种方案,我可以打个电话给中介,让中介给我找。这样的优势就是,我和真正去找房子的人没有直接的联系。如果朋友临时有事,可能就不能帮忙给我找了。但是,中介就不会发生这种情况;所以,当我们要做一件事的时候,并不需要把做事的人拉进来,而只需要下订单,把事情外包给专门做这种事情的人去做,具体是谁就不要管那么多;这样,可以随时更换外包公司,而不影响自身业务;
五、接口隔离原则
定义:客户端不应该依赖它不需要的接口,也可以说是类间的依赖要建立在最小的接口的基础上进行。
理解:小明是人类中的一个实例对象,他有工作挣钱的能力,也有消费付款的能力。那么,对于他供职的公司来说,只需要依赖他工作的能力。对于商场的店主来说,当他消费的时候,就只需要依赖他付款的能力。小明这两项能力,分别对外提供两个接口。那么,公司来说,就看不到付款的接口。对于店主来说,就看不到他工作的接口。如果,哪天小明换了个工作。付款这个接口是没啥影响的。同样的,小明换了一家店消费。对于他供职的公司来说,也没任何影响。就这样,两个接口完美的隔离开。
六、迪米特原则
定义:也称最少知道原则,即一个对象应该对其他对象有最少的了解。
理解:其实就是一个类尽最大努力减少对其他类的耦合,同时依赖了一个类也应该将一些方法最少的公开。知道的越少,相互之间的关心的就越少,耦合也就越小。如果有一天,一个类要修改,那么考虑之间的牵连就越少,扩展越容易。
扩展:这里说说怎么执行,我觉得其实很简单,如下:
尽最大的努力隐藏自己。对于Java来说,就是class、方法、变量的描述符,优先级依次从 private 、缺省、protect 、public 的顺序来,能隐藏的绝对不暴露。尤其强调用好包内class的缺省描述,因为实际上而言。既然是已经分了一个包了,那么这个包内有相同的业务职责,理想化的结果就是一个包只有一个对外的public的接口类,而其余都隐藏。
尽最大的努力不依赖别人。这里很好看,对于Java来说,看看自己的class类的import,如果有一大堆的import,尤其看着和自己业务属性无关的import,那么是得考虑进行重构了。
关于依赖倒置和好莱坞原则:
好莱坞原则(Hollywood Principle)
别打电话给我们,有事我会打电话给你。
作用:防止“依赖腐败”
当高层组件和底层组件相互依赖,高层组件又依赖边侧组件,边侧组件又依赖底层组件.依赖腐败就产生了,系统的设计就很难搞的懂...
解释:
在好莱坞原则之下,我们允许低层组件将自己挂钩到系统上,但是高层组件会决定什么时候和怎样使用这些低层组件。换句话说,高层组件对待低层组件的方式是“别调用我们,我们会调用你”
应用:
模板方法模式就应用到了这个原则,模板方法类对它的子类说: 不要调用我们,我们会调用你
好莱坞和依赖倒置原则的区别
依赖倒置原则 面向接口或者抽象类编程
好莱坞原则 子类的(底层)尽量不要调用超类(父类)的方法
关于常见的依赖倒置的框架
一般说到依赖倒置原则,脑子想到的就是依赖倒置、控制反转、依赖注入这些术语。在各个技术栈都有一个月。在Java目前最常用的就是Spring后端框架.而Spring依赖注入的实现技术是:动态代理。
随笔:这些知识点已经非常熟悉,也分析过不少的框架的源码。平时设计也遵从这些原则。
推荐一本书叫做《大话设计模式》
评论