Table of Contents
关于
之前读过这本书,但是读的不够仔细,现记录一些笔记和想法,增加理解。
第一部分 6大设计原则
第1章 单一职责原则
- 用户类设计,属性和行为拆分为两个接口,分别负责
- 单一职责原则:应该有且只有一个原因引起类的变更。一个接口只封装一种变化!!
- 接口一定要做到单一职责,类的设计尽量做到只有一个原则引起变化
- 「变更才显真功夫」
第2章 里式替换原则
- 子类跟父类的关系
- 里式替换原则:所有能引用基类的地方必须能透明地使用其子类对象
- 在类中调用其他类时,无必要使用父类或接口,如果不能使用父类或接口,则说明类的设计已经违背了里式替换原则。也就是面向接口编程,而不是面向实现编程
第3章 依赖倒置原则
- 原则:
- 高层模块不应该依赖低层模块,两者都应该依赖其抽象
- 抽象不应该依赖细节
- 细节应该依赖抽象
- Java语言版
- 模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系通过接口或者抽象类产生
- 接口和抽象类不依赖于实现类
- 实现类依赖接口或抽象类
- 好处:
- 减少类间耦合,提高系统稳定性
- 当扩展新的功能时,不用修改现有模块的实现
- 降低并行开发引起的风险
- 只依赖抽象的实现,可以独立测试和并行开发
- 提高代码的可度性和可维护性
- 减少类间耦合,提高系统稳定性
- 尽量不要复写基类的方法,这对依赖的稳定性会产生一定的影响
第4章 接口隔离原则
- 接口:既包括抽象类,也包括具体类
- 隔离:
- 客户端不应该依赖它不需要的接口
- 类间的依赖关系应该建立在最小的接口上
- 已经被污染的接口,尽量去修改,若变更的风险较大,则采用适配器模式进行转化处理
第5章 迪米特法则
- 一个对象应该对其他对象有最少的了解
- 类只跟朋友类交互,而不跟朋友类的第三个类交互。
- 不要出现
getA().getB().getC().getD()
这种情况,除非返回的类型是一样的;一般跳转不要超过两次 - 不要出现在类A中,调用类B的方法1,方法2,方法3,具体方法调用过程不应该是A要关心的,而是B要关心的。所以B应该提供一个统一的方法X来实现具体调用操作,而A只跟B的方法X交互即可。
第6章 开闭原则
- 一个软件实体如类、模块和函数应该对扩展开放,对修改关闭
- 一个软件实体应该通过扩展来实现变化,而不是通过修改已有的代码来实现变化
- 最基础的一个原则!!!前五章都是开闭原则的具体形态!!这才是精神领袖!!
-
重要性:
- 测试友好,扩展新功能无序重新测试原有逻辑
- 提高复用性
- 提高可维护性,维护人员最喜欢的是扩展一个类,而不是修改一个类
-
最佳实践
- 开闭原则也只是一个原则,适当时可以扩充。类高内聚低耦合
- 项目规章非常重要。应尽量让自己的项目成员稳定,稳定后才能建立高效的团队文化,章程是一个团队所有成员共同的知识结晶
- 预知变化,才能拥抱变化
一篇文章导读
- 哪种人是软件设计中的稀缺型人才?
- 接口有什么好处(Why)
- 制定标准:分工协作的前提就是标准化。「一流的企业做标准,二流的企业做品牌,三流的企业做产品」
- 提供抽象:调用者和实现者可以完全的解耦。
> 一旦你融会贯通的掌握了这个强大的技巧——面向抽象、面向接口,你会发现,虽然面向实现和面向接口在代码层面的差异不大,但是其背后所隐含的设计思想和设计理念的差异,不亚于我篮球水平和詹姆斯篮球水平之间的差异!
> 而这种可以跳出细节内容,站在更高抽象层次上,来看整个系统的模块设计、模块划分、模块交互的人,正是我们软件设计队伍中,非常稀缺的人才。有时候,我们也管这些人叫架构师。
- 什么时候要用接口(When)
- 有扩展性需求的时候
- 需要解耦的时候:java的logger
- 要给外界提供API的时候:类似于这种API的情况,都是在倒逼开发者要把接口想清楚。我想,这也算微服务架构一个漂亮的“副作用”吧。当原来单体应用里的各种耦合的业务模块,一旦被服务化之后,就自然而然的变成“面向接口”的了。
- 通过依赖倒置来实现面向接口(How)
- 什么时候不需要接口
- 想不清用接口的好处的时候:和许多其它软件原则一样,面向接口很好,但也不应该是不分背景、不分场合胡乱使用的杀手锏和尚方宝剑。因为过多的使用接口,过多的引入间接层也会带来一些不必要的复杂度。
个人思考
- 面向接口设计,我理解的是自顶向下设计,即从最上层抽象开始设计最少功能的接口
- 一个具体实现的案例 推荐引擎设计-自顶向下设计