设计模式之禅-1
六大设计原则
一 单一职责原则(SPR)
单一职责原则定义:There should nerver be more than one reason for a class to change.
好处:类的复杂性降低,可读性、可维护性提高,降低修改引入问题的风险
单一职责原则难点在于如何界定“职责”,要结合具体项目分析。单一职责原则适用于类、接口,同样也适用于方法。在实际开发过程中,尽量保证接口符合单一职责原则,类的设计尽量保证只有一个原因引起变化。
二 里氏替换原则(LSP)
里氏替换原则定义:所有引用基类的地方必须能透明地使用其子类的对象。
思考:继承带来的优点:代码共享,每个子类都拥有父类的方法和属性;提高代码重用性等。 缺点:继承是侵入性的,子类必须拥有父类的所有方法跟属性;增强耦合性,当父类被修改的时候,需要考虑子类。
里氏替换原则为良好的继承定义了规范。
- 子类必须完全实现父类的方法。 在类中调用其他类时务必使用父类或接口,如不能使用,说明类的设计违背了LSP。如果子类不能完整的实现父类的方法,或者父类某些方法在子类中“畸变”,则建议断开父子继承关系,采用依赖、聚合、组合等关系代替继承。
- 子类可以有自己的个性。 体现在 LSP不能反过来用。 子类出现的地方父类不一定能替换。
- 覆盖或实现父类的方法时入参可以被放大。
- 覆盖或实现父类的方法时返回值可以被缩小。
三 依赖倒置原则(DIP)
三层含义:高层模块不应该依赖低层模块,二者都应该依赖抽象;抽象不应该依赖细节;细节应该依赖抽象。
在java语言中,抽象就说指抽象类或接口,细节指的是抽象类或接口的实现类。所以依赖倒置原则在java中的表现就是:
- 模块间依赖通过抽象发生,实现类之间不发生直接依赖关系,其依赖关系通过接口或抽象类产生的。
- 接口或抽象类不依赖于实现类
- 实现类依赖接口或抽象类
更加精简的定义就是,面向接口编程。
优点:减少类间的耦合,提供系统稳定性,降低并行开发带来的风险(依赖接口定义即可,不依赖具体实现)
依赖的三种实现方式:
- 构建函数传递依赖对象 (在实现类中有定义好的变量存储依赖的对象)
- 通过Setter方法传递依赖对象(在实现类中有定义好的变量存储依赖的对象)
- 接口声明依赖对象(接口注入)
四 接口隔离原则
定义: client 不应该依赖它不需要的接口;类间的依赖关系应该建立在最小的接口上。简单概括,建立单一接口,接口尽量细化,方法尽量要少。
ps:单一职责原则注重的是业务逻辑上职责的划分。接口隔离原则注重接口方法要少。二者关注点不同。
五 迪米特法则(LOD)
又称最少知识原则。一个对象应该对其他对象有最少的了解。
4层含义:
- 只和朋友交流。朋友类定义是出现在成员变量、方法的输入输出参数中的类。
- 朋友间也是有距离的.尽可能减少暴露public属性或方法。
- 是自己的就是自己的。 如果一个方法放在本类中,既不增加类间关系,也对本类不会造成负面影响,那就放置在本类中。
- 谨慎使用Serializable。
核心观念是类间保持低耦合,代价是存在中转类。
六 开闭原则
定义:一个软件实体如类、模块、和函数应该对扩展开放,对修改关闭。即软件实体应该通过扩展来实现变化,而不是通过修改已有代码。
前面五条原则是对开闭原则的具体解释。
应用思路:
抽象约束:第一 通过接口或抽象类约束扩展,对扩展进行辩解约束,不允许出现在接口或抽象类中不存在的public方法;第二 参数类型、引用对象尽量使用接口或抽象类,而不是实现类;第三,抽象层尽量保持稳定,一旦确认不允许修改。
尽量使用配置数据来控制程序行为。
封装变化,将相同变化封装到一个接口或抽象类中。 找到预计有变化或不稳定的点,为这些变化点创建稳定的接口,一旦感觉有变化可以进行封装。 23个设计模式都是从不同角度对变化进行封装的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南