☰
常见设计原则
2026/10/5 9:18:09 网站建设 项目流程

设计模式 7 大设计原则(SOLID + 迪米特 + 合成复用)

一句话总纲:目的是降低耦合、提高复用、易于扩展、方便维护

1. 单一职责原则 SRP(Single Responsibility Principle)

定义:一个类只负责一件事,只有一个引起它变化的原因。

类的职责尽量单一,不要写万能类。

❌ 反例:User类,同时包含用户信息保存、密码加密、发送邮件、生成报表。用户改字段、邮件模板变都会改这个类。 ✅ 正例:

  • User:仅用户实体属性
  • UserRepository:数据库保存
  • EmailService:发邮件

2. 开闭原则 OCP(Open-Closed Principle)

定义:对扩展开放,对修改关闭。新增功能尽量加代码,不要修改原有成熟代码。

❌ 反例:图形计算面积,if else判断圆形、矩形,新增三角形要修改原有getArea方法。 ✅ 正例:抽象Shape接口,有getArea();圆形、矩形、三角形各自实现接口。新增图形不用改旧代码,新增一个类即可。

3. 里氏替换原则 LSP(Liskov Substitution Principle)

定义:子类可以完全替换父类,程序行为不会出错。子类不能破坏父类原有逻辑。

❌ 反例:父类Rectangle有宽高set;子类Square正方形继承矩形,setWidth同时修改height。把正方形当矩形传入计算函数会出错。 ✅ 正例:正方形和矩形不继承,共同实现一个图形接口。

核心:继承不能随便用,子类不能重写后改变父类原有行为。

4. 接口隔离原则 ISP(Interface Segregation Principle)

定义:不要大而臃肿的接口,拆分细接口;类不需要的方法,就不要强迫它实现。

❌ 反例:一个大接口Worker包含work()、eat()、sleep();机器人实现这个接口,被迫空实现eat、sleep。 ✅ 正例:拆成Workable、Eatable、Sleepable多个小接口。机器人只实现Workable。

5. 依赖倒置原则 DIP(Dependency Inversion Principle)

定义:高层模块不要依赖低层模块,二者都依赖抽象;抽象不依赖细节,细节依赖抽象。

❌ 反例:业务Service直接new MySQLDao,Service强依赖MySQL实现,换成Oracle就要改Service代码。 ✅ 正例:定义UserDao接口;MySQLUserDao、OracleUserDao实现接口。Service依赖UserDao接口,运行时注入具体实现。(Spring依赖注入就是典型)


6. 迪米特法则 LoD(最少知道原则)

定义:一个对象尽量少了解其他对象内部细节,只和直接朋友通信,不要访问陌生对象。

不要链式调用a.getB().getC().doSomething(),这就是典型违反迪米特。

❌ 反例:老板直接找员工的下属安排任务,老板知道太多内部层级。 ✅ 正例:老板只找主管,主管再安排下属;老板不接触底层员工。

符合迪米特的写法:

// B类新增方法,把C的动作包起来 class B{ private C c; public void doCWork(){ c.doSomething(); // B自己和C交互,A看不到C } } // A只和B打交道,完全不知道C的存在 B b = a.getB(); b.doCWork();

7. 合成复用原则 CRP(组合优于继承)

定义:优先使用组合/聚合来复用代码,少用继承。

继承是强耦合;组合是弱耦合,更灵活。

❌ 反例:Car继承Engine来复用引擎代码,引擎是车的部件,不是“车是引擎”。继承是is-a关系。 ✅ 正例:Car里面持有Engine对象(组合),class Car { private Engine engine; },可以动态更换不同引擎。

快速记忆口诀

单、开、里、接、依,迪米特,合成优先SOLID 对应前5条:SRP OCP LSP ISP DIP

面试精简版

  1. 单一职责:一个类只做一件事
  2. 开闭原则:扩展开放,修改关闭
  3. 里氏替换:子类可替换父类,不破坏逻辑
  4. 接口隔离:细分接口,不强迫实现不需要方法
  5. 依赖倒置:依赖抽象,不依赖具体实现
  6. 迪米特法则:最少知道,减少对象间耦合
  7. 合成复用:优先组合,少用继承

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询