架构师训练营 W2 学习心得
SOLID
S:The Single-Responsibility Principle (SRP) / 单一职责
一个类或模块只负责完成一个职责(或者功能)。一个类或者模块包含了两个或者两个以上业务不相干的功能,我们就认为职责不够单一,应该将它拆分成多个功能更加单一、粒度更细的类或模块。拆分的维度会随业务不同阶段的需求背景而改变。重点是需要持续重构。一些参考拆分- 类中的代码行数、函数或者属性过多;最好不能超过 200 行,函数个数及属性个数都最好不要超过 10 个。- 类依赖的其他类过多,或者依赖类的其他类过多;- 私有方法过多;- 比较难给类起一个合适名字 ;- 类中大量的方法都是集中操作类中的某几个属性 ;拆分之后,如果代码的可维护性变差,就该打消念头。单一职责原则是为了实现代码高内聚、低耦合,提高代码的复用性、可读性、可维护性。
O:The Open/Closed Principle (OCP) / 开闭原则
开闭原则追求的扩展性是代码质量最重要的衡量标准之一。添加一个新的功能应该是,在已有代码基础上扩展代码(新增模块、类、方法等),而非修改已有代码(修改模块、类、方法等)。只要它没有破坏原有的代码的正常运行,没有破坏原有的单元测试,我们就可以说,这是一个合格的代码改动。开闭原则并不是说完全杜绝修改,而是以最小的修改代码的代价来完成新功能的开发。同样的代码改动,在粗代码粒度下,可能被认定为“修改”;在细代码粒度下,可能又被认定为“扩展”。需要在扩展性和可读性之间做权衡。
L:The Liskov Substitution Principle (LSP) / 里式替换原则
子类对象(object of subtype/derived class)能够替换程序(program)中父类对象(object of base/parent class)出现的任何地方,并且保证原来程序的逻辑行为(behavior)不变及正确性不被破坏。父类定义了函数的“约定”(或者叫协议),那子类可以改变函数的内部实现逻辑,但不能改变函数原有的“约定”。违反里式替换原则的例子 1. 子类违背父类声明要实现的功能 2. 子类违背父类对输入、输出、异常的约定: 子类对输入的数据的校验比父类更加严格,那子类的设计就违背了里式替换原则。 3. 子类违背父类注释中所罗列的任何特殊说明小窍门,那就是拿父类的单元测试去验证子类的代码。如果某些单元测试运行失败,就有可能说明,子类的设计实现没有完全地遵守父类的约定,子类有可能违背了里式替换原则。
I:The Interface Segregation Principle (ISP) / 接口分离原则
“接口”理解为下面三种东西:一组 API 接口集合、单个 API 接口或函数OOP 中的接口概念如果把“接口”理解为一组接口集合,可以是某个微服务的接口,也可以是某个类库的接口等。如果部分接口只被部分调用者使用,我们就需要将这部分接口隔离出来,单独给这部分调用者使用,而不强迫其他调用者也依赖这部分不会被用到的接口。如果把“接口”理解为单个 API 接口或函数,部分调用者只需要函数中的部分功能,那我们就需要把函数拆分成粒度更细的多个函数,让调用者只依赖它需要的那个细粒度函数。如果把“接口”理解为 OOP 中的接口,也可以理解为面向对象编程语言中的接口语法。那接口的设计要尽量单一,不要让接口的实现类和调用者,依赖不需要的接口函数。
接口隔离原则与单一职责原则的区别
接口隔离原则提供了一种判断接口的职责是否单一的标准:通过调用者如何使用接口来间接地判定。如果调用者只使用部分接口或接口的部分功能,那接口的设计就不够职责单一。
D:The Dependency-Inversion Principle (DIP) / 依赖倒置原则
- 高层模块不应该依赖低层模块,两者都应该依赖其抽象;
- 抽象不应该依赖细节;
- 细节应该依赖抽象。
评论