设计模式-01-设计原则
🔑 设计原则
🚀 什么是设计原则?
设计原则就像是 写好代码的“潜规则”或“习惯”,是你写程序时脑子里要时刻记住的准则。
这些原则不是强制的,但如果你违背它,代码可能会:
很难扩展
一改就崩
到处耦合(缠在一起)
谁也看不懂
✅ 一、单一职责原则(SRP)
Single Responsibility Principle
📖 含义:一个类/方法,只做一件事。
就像你请一个人做事,他只能干一件事情,不要让他又修电脑、又炒菜、还带孩子。
🧠 举例:
1 | class UserService { |
这就错了!UserService 应该只管用户业务,发邮件应该放到 EmailService 去。
✅ 二、开闭原则(OCP)
Open Closed Principle
📖 含义:对扩展开放,对修改关闭。
也就是说,当有新需求时,应该增加代码而不是改老代码,不然容易出 bug。
🧠 举例:
你做了一个支付功能,原来只支持微信,后来要支持支付宝、银行卡:
❌ 错误写法:改老代码增加 if-else
1 | if ("wechat".equals(payType)) { |
✅ 正确写法:新增一个支付策略类,不改老代码
1 | interface PayStrategy { void pay(); } |
✅ 三、里氏替换原则(LSP)
Liskov Substitution Principle
📖 含义:子类必须能替换父类,且行为不出问题。
🧠 举例:
你写了一个Bird类有个fly()方法,后来你写了Penguin extends Bird,但企鹅不能飞!
这是错误设计,企鹅 不应该继承会飞的鸟类。否则如果代码中用到了 Bird.fly(),企鹅对象就会出问题。
✅ 解决:拆分接口,把会飞的鸟放到
FlyingBird类中。
❌ 错误案例:
1 | class Bird { |
企鹅不会飞,但继承了鸟类的 fly(),这违反了里氏替换:你以为是鸟,结果崩了。
✅ 正确做法:
拆分类层级,不要让不会飞的类继承飞行鸟类。
1 | interface Bird { void layEggs(); } |
✅ 四、依赖倒置原则(DIP)
Dependency Inversion Principle
📖 含义:高层代码不要依赖底层实现,要依赖接口(抽象)。
也就是说,不要直接 new 实现类,要用接口去约定行为。
🧠 举例:
❌ 错误写法:
1 | class OrderService { |
这就死死绑定了支付宝。将来换微信支付,全系统都得改!
✅ 正确写法:
1 | interface IPay { void pay(); } |
引出了支付功能的实战例子:
既然用接口去支付,那么如何知道用户使用支付宝或者微信支付呢,从哪里来判断?
✅ 五、接口隔离原则(ISP)
Interface Segregation Principle
📖 含义:接口不要太大,只暴露“需要”的方法。
🧠 举例:
❌ 错误接口:
1 | interface Animal { |
让猪也实现 fly()?太离谱了!
✅ 正确接口:
1 | interface Runnable { void run(); } |
✅ 六、迪米特法则(LOD)
Law of Demeter
📛 命名背景:
又叫“最少知识原则(Least Knowledge Principle,LKP)”,1987 年提出。Demeter 是一个项目名。这个原则强调:对象之间不要知道太多别人的信息,以避免耦合。
📖 含义:只和你认识的对象打交道,不要深层次访问别人的对象。
也就是说,一个对象应该只与它“直接的朋友”通信,避免链式调用或内部暴露。
🧠 举例:
❌ 错误写法:
1 | school.getTeacher().getStudent().getName() // 多层访问 |
你只认识 school,就去找 teacher 的 student,这样代码耦合太深,改动一个地方就全挂。
✅ 正确写法:
1 | school.getStudentName() // 让 School 内部去封装实现细节 |
让 School 提供你需要的信息,不暴露内部结构。
✅ 七、组合/聚合复用原则(CARP)
Composite/Aggregate Reuse Principle
📖 含义:优先使用组合(“有一个”),而不是继承(“是一个”)。
继承太强,子类太容易被牵连。该原则强调:优先使用对象组合,而不是类继承。
继承是一种强耦合的方式,尽量通过组合已有类来实现功能,而不是继承。
🧠 举例:
❌ 错误写法:
1 | class ElectricCar extends Car { |
✅ 正确写法:
1 | class ElectricCar { |
🧠 总结口诀(记忆辅助):
| 原则名 | 口诀 |
|---|---|
| 单一职责 | 一类一事,不要多管闲事 |
| 开闭原则 | 增加功能,不动旧代码 |
| 里氏替换 | 子类能替代,父类不出事 |
| 依赖倒置 | 面向接口,不 new 实现 |
| 接口隔离 | 接口要小,不要大杂烩 |
| 迪米特法则 | 不串门,封装好边界 |
| 组合复用 | 多组合,少继承 |
设计模式-01-设计原则