面向对象的六大原则——SOLID原则+迪米特法则
- 单一职责原则(Single Responsibility Principle)
- 开闭原则(Open/Closed Principle)
- 里氏替换原则(Liskov Substitution Principle)
- 接口隔离原则(Interface Segregation Principle)
- 依赖倒置原则(Dependency Inversion Principle)
- 迪米特法则(Law of Demeter)
引用:六大法则的地位 “可以说是正好处于语法规则与常见的设计模式之间。与语法规则相比,不严格遵守也不影响程序编译运行,但是任意违背这些法则的代码设计,从设计上来说都会是绝对错误的,在整个程序系统的代码中都是极具破坏性的。也因此,我们称之为‘原则’或‘法则’,区别于旨在优化程序设计架构的‘模式’或是‘思想’。”
单一职责原则(Single Responsibility Principle)
- 一个类中只承担一种功能。是复用的基础。
- 降低耦合性
- 增强可读性与可维护性
- 增强复用性
开闭原则(Open/Closed Principle)
- “对扩展开放,对修改封闭”
- 在实践上,当我们需要改变或添加功能时,应该尽量通过扩展编写新的代码,而不是修改已有的代码。
- 同理,当我们设计一个类结构时,也应当提前考虑,当需求扩展或变更时能够通过添加而不是删改来实现新的需求。
- 预防性措施:防止修改操作引入新的bug (如果一段代码能跑就不要动它.jpg)
- 提高灵活性:符合开闭原则的易扩展结构,可以更好的应对需求变化。(尤其对于游戏开发)
- 最简实践示例:子类重写父类的方法
- 只要父类的设计足够抽象、职责边界明确,子类就能通过继承并重写父类的某些方法来满足新的需求或实现新的功能,这就达到了在不动原有代码的前提下进行扩展的目的。
- 对扩展开放:当需求发生变化或新增功能时,可以通过创建新的子类并在其中实现新的逻辑(重写父类方法)来满足需求;
- 对修改封闭:已有的父类代码无需进行修改,从而减少对已稳定代码的干扰,也降低引入新 Bug 的风险。
- 只要父类的设计足够抽象、职责边界明确,子类就能通过继承并重写父类的某些方法来满足新的需求或实现新的功能,这就达到了在不动原有代码的前提下进行扩展的目的。
里氏替换原则(Liskov Substitution Principle)
- 所有父类对象出现的地方都可以使用子类对象来替换,而不影响程序的正确性。
- 呼应了“继承”所要求的:子类是父类的更具象描述,而同时遵循与父类相同的功能。
- 保证继承体系的正确性:不遵循父类契约的子类可能会引发意料外的问题。
- 提高复用性:符合LSP的设计能使得多态机制充分发挥。
- 实践中具体要求:
- 子方法的参数类型需与父方法参数类型相匹配或更抽象(即“更父”)
- 子方法的返回值类型需与父方法返回值类型相匹配或更具体(即“更子”)
- 子方法不应抛出父方法预期之外的异常类型
- 子方法不应加强“前置条件”
- 子方法不能削弱“后置条件”
- 子类需要遵循父类的潜在设计规范
- 指一些语法外的,形式上的设计规则
- 确保子类的设计正确理解了父类的设计抽象
- 子类不能修改父类中私有成员变量的值
其实上述看似繁杂要求就是为了保证子类一定任何情况都能替换父类
接口隔离原则(Interface Segregation Principle)
- 功能更细分的小接口,优于大而全的实现多重功能的接口。
- 与单一职责的思想类似。
引用 越简单,越不容易产生多余的依赖和耦合,越容易完成更具灵活性无副作用的架构。
依赖倒置原则(Dependency Inversion Principle)
- 高层次的类不应该直接依赖低层次的类,应该将二者的依赖转嫁到抽象接口之上。
- 高低层次不是指有继承关系的具体子父类,而是软件功能架构层面的。
- 高层次:软件层次的上层业务(按钮响应、界面显示等)
- 低层次:软件层次的底层架构(文件IO、网络通信、数据库连接等)
- 高低层次不是指有继承关系的具体子父类,而是软件功能架构层面的。
- 就是在强调接口概念的解耦合功能。
迪米特法则(Law of Demeter)
- 一个对象只与其最直接关联的对象进行通信,而不会与陌生对象产生耦合。
- 就是说避免任何链式调用,控制类间的逻辑耦合度。
- 也被称为“最少知识法则”。
- 降低耦合性
- 避免产生链式调用的逻辑
- 减少对象间的依赖,防止因某对象变化影响过多其他对象。
- 增强系统稳定性可维护性
- 每个模块只关注自己的直接关系
- 降低耦合性