设计模式(23种设计模式)并不是凭空发明出来的,它们大多遵循面向对象设计的 6 大原则(SOLID + 迪米特法则)。
可以理解为:
设计原则 → 设计模式 → 具体代码就像:
交通法规 → 驾驶技巧 → 开车先有原则,再有模式。
文章目录
- 1. 单一职责原则(Single Responsibility Principle,SRP)
- 核心思想
- 错误示例
- 改进
- 小学生版
- 实际工程
- 2. 开闭原则(Open-Closed Principle,OCP)
- 核心思想
- 例子
- 小学生版
- 3. 里氏替换原则(Liskov Substitution Principle,LSP)
- 核心思想
- 正确
- 错误经典案例
- 小学生版
- 4. 接口隔离原则(Interface Segregation Principle,ISP)
- 核心思想
- 错误
- 正确
- 小学生版
- 5. 依赖倒置原则(Dependency Inversion Principle,DIP)
- 核心思想
- 错误
- 正确
- 小学生版
- 6. 迪米特法则(Law of Demeter,LoD)
- 核心思想
- 错误
- 正确
- 小学生版
- 一张图记住 6 大原则
- 在实际开发中什么时候最有感?
1. 单一职责原则(Single Responsibility Principle,SRP)
核心思想
一个类只负责一件事。
错误示例
classUserService{voidlogin(){}voidregister(){}voidsendEmail(){}voidgenerateReport(){}}这个类既负责:
- 用户管理
- 邮件发送
- 报表生成
职责太多。
改进
classUserService{}classEmailService{}classReportService{}每个类只负责自己的事情。
小学生版
学校里:
班长 学习委员 体育委员各管各的。
不要:
一个同学 负责全班所有事情否则累死。
实际工程
例如 YOLO 项目:
Dataset Model Trainer Validator分别负责:
- 数据
- 模型
- 训练
- 验证
而不是全部塞进一个类。
2. 开闭原则(Open-Closed Principle,OCP)
核心思想
对扩展开放,对修改关闭。
新增功能:
尽量新增代码 不要修改旧代码例子
支付系统:
interfacePayment{voidpay();}已有:
classWeChatPayclassAlipayPay新增:
classApplePay直接扩展即可。
不用:
if(type=="wechat")if(type=="alipay")if(type=="apple")不断修改旧代码。
小学生版
插线板:
增加新电器 直接插进去而不是:
每买一个电器 拆一次墙3. 里氏替换原则(Liskov Substitution Principle,LSP)
核心思想
子类必须能够替换父类。
正确
Animal├─Dog└─Cat哪里需要:
Animal都能传:
DogCat错误经典案例
Rectangle继承:
Square因为:
正方形 ≠ 长方形行为不同。
违反里氏替换。
小学生版
如果老师说:
带一只动物来你带:
小狗没问题。
但如果带:
机器人就不行。
4. 接口隔离原则(Interface Segregation Principle,ISP)
核心思想
不要让一个类依赖它不需要的方法。
错误
interfaceAnimal{fly();swim();run();}企鹅:
classPenguinimplementsAnimal结果:
fly()根本不会飞。
很尴尬。
正确
拆分:
interfaceFlyable{}interfaceSwimmable{}interfaceRunnable{}需要什么实现什么。
小学生版
学校发了一张万能学生证:
学生证
□ 游泳馆 □ 图书馆 □ 实验室 □ 停车场 □ 教师办公室一年级小学生:
只需要:
✓ 图书馆结果:
必须携带全部权限
这就有问题。
更合理的是:
图书馆证 游泳馆证 实验室证按需发放。
这就对应:
interfaceReadable{}interfaceSwimable{}interfaceExperimentable{}5. 依赖倒置原则(Dependency Inversion Principle,DIP)
核心思想
依赖抽象(标准),不依赖具体实现。
高层模块不应该依赖低层模块,两者都应该依赖抽象。
错误
classPerson{Carcar=newBMW();}Person绑死BMW。
正确
classPerson{Carcar;}其中:
interfaceCar{}具体实现:
BMWTeslaBYD随便换。
人 ↓ 汽车接口(Car) ↓ 宝马 特斯拉 比亚迪小学生版
家里的手机、电视、风扇都使用统一标准的插头。
因此:
换一个品牌的插座,
这些电器仍然能用;
换一个品牌的电器,
插座也不用改。
大家依赖的是“标准”,
而不是彼此。
这就是依赖倒置原则。
6. 迪米特法则(Law of Demeter,LoD)
也叫:
最少知道原则(Least Knowledge Principle)
核心思想
只和直接朋友说话。
错误
person.getCompany().getDepartment().getManager().getPhone()访问链太长。
正确
person.getManagerPhone()由内部处理。
小学生版
你想借一本书。
正常:
你 ↓ 图书管理员 ↓ 找到书你不需要知道:
第几排 第几个书架 第几层 第几个格子如果你必须知道:
图书馆布局那以后图书馆重装修:
全乱套这就是:
少知道 少耦合一张图记住 6 大原则
| 原则 | 关键词 | 一句话总结 |
|---|---|---|
| SRP | 单一职责 | 一个类只负责一种职责 |
| OCP | 开闭原则 | 扩展开放,修改关闭 |
| LSP | 里氏替换 | 子类替换父类后行为保持正确 |
| ISP | 接口隔离 | 别逼别人实现不用的方法 |
| DIP | 依赖倒置 | 依赖抽象,不依赖具体实现 |
| LoD | 迪米特法则 | 少了解别人的内部细节 |
在实际开发中什么时候最有感?
很多开发者刚学设计模式时会觉得:
“这些原则很抽象,平时写业务代码根本用不到。”
实际上,当项目从:
1000 行代码增长到:
10万+ 100万+时,这些原则开始体现价值。
例如你做过 YOLO 改模型:
新增 Backbone 新增 Neck 新增 Attention 新增 Loss如果代码遵循:
- 开闭原则
- 依赖倒置
你只需要:
model=build_model(cfg)增加一个 YAML 配置即可。
如果没遵循这些原则,可能需要改十几个文件,甚至引入新的 Bug。
所以设计模式的本质不是“炫技”,而是:
降低修改成本,提高代码可维护性和可扩展性。
对于 AI 工程来说,最常见、最有价值的通常是:
- 单一职责原则(模块拆分)
- 开闭原则(方便扩展新模型)
- 依赖倒置原则(配置驱动、插件化)
这三条几乎贯穿了从 PyTorch 框架到大型训练平台的设计。