整体就是为了实现 “高内聚,低耦合”

单一功能原则 - SRP

就一个软件实体,只会因为一个原因而变化。 拒绝“瑞士军刀”类型的代码。

Just because you can , doesn’t mean you should

如果不是单一变化,那么变化会朝着依赖的反方向进行传递

一个类或者模块只负责完成一个职责(或者功能)

保证我们在设计函数、方法时做到功能单一,权责明确,当发生改变时,只有一个改变它的原因。如果函数/方法承担的功能过多,就意味着很多功能会相互耦合,这样当其中一个功能发生改变时,可能会影响其它功能。单一功能原则,可以使代码后期的维护成本更低、改动风险更低。

还可以基于代理完成SRP 原则:

开闭原则 Open Closed Principle - OCP

软件实体应该对扩展开放、对修改关闭。

通过在已有代码基础上扩展代码,而非修改代码的方式来完成新功能的添加。开闭原则,并不是说完全杜绝修改,而是尽可能不修改或者以最小的代码修改代价来完成新功能的添加。

本质上使用抽象和多态。 面对具体实现编程了,没有使用抽象和多态类型,是一个不好的例子

将 switch 逻辑修改到了工厂类里面

修改老的代码之后,如果没有单元测试 , 那么就不知道这个改动的影响范围。

OCP的一个弊病就是盲目引入不成熟的抽象,不要对所有内容做无畏的扩展,而是对频繁变化的部分做出抽象。

“只对第一课子弹击中”: 当变化发生的时候,创建抽象来隔离以后同类的变化。

Liskov Substitution Principle - 里氏替换原则 - LSP

支持抽象和多态的关键机制是继承 , 什么才是好的继承关系?

“所有引用到基类的地方,必须可以透明的使用其子类的对象” 如果S是T的子类型,则类型T的对象可以替换为类型S的对象,而不会破坏程序。

继承的时候应该更多的关注父子类之间的行为,而不是关注其属性。

继承属于白盒复用的模式 ,即父类的实现是透明的; 组合是黑盒复用的模式 。

不合理的继承关系

由父子变为了兄弟,但是普通轿车违反了 SRP原则

Interface Segregation Principle - 接口隔离原则 -ISP

客户端程序不应该依赖它不需要的方法 , 不要强迫用户去依赖他们不使用的接口。

严格意义上,其实 违反了 ISP,就是违反了 SRP 原则

Do Nothing 的坏味道

多接口分离接口

对象的组合 和 包裹 完成,即适配器模式

对于上述普通轿车违反了SRP 原则 ,其实表现就是违反了 ISP 原则

Dependency Inversion Principle - 依赖倒置原则 - DIP

DIP 主要是完成 技术和业务相分离的作用

高层模块不要依赖底层模块,而是依赖于抽象;抽象不依赖细节,细节依赖于抽象。

变化会朝向依赖的反方向传递

依赖于抽象而不是一个实例,其本质是要面向接口编程,不要面向实现编程

如果高层模块直接依赖底层模块 , 底层的改动会直接影响到了高层;

比如底层的持久化从文件切换到数据库,高层应该无法感知到。

好的设计必须是分层的,层与层之间的通信使用的是抽象。

接口属于高层 , 低层实现接口 , 把自己挂在高层。