面向对象六大设计原则是可落地的实践指南:单一职责强调按变化原因拆分职责;开闭原则主张通过抽象扩展而非修改;里氏替换要求子类安全替代父类;接口隔离、依赖倒置和迪米特法则协同降低耦合。

面向对象六大设计原则不是抽象教条,而是日常编码中可落地的实践指南。它们不强制你写某种结构,而是帮你判断“这样写是否容易改、是否容易加、是否容易懂”。在 Java 中应用,关键不是背定义,而是理解每条原则解决什么问题、在哪些地方最容易踩坑。
单一职责原则:一个类只做一件事
核心是识别“变化原因”——如果某类因为登录逻辑变要改,又因为报表格式变也要改,它就违反了 SRP。Java 中最常见反例是把数据访问、业务校验、结果封装全塞进一个 Service 类。
- 拆分方式:按职责边界切分接口和实现,比如 UserRepository(只管查存)、UserValidator(只管校验)、UserAssembler(只管 DTO 转换)
- 注意粒度:方法级也适用——一个方法别既查库又发消息还写日志;类级更关键,但不必过度拆分(如用户姓名和邮箱变更频率一致,可保留在同一 VO 中)
开闭原则:新增功能靠加代码,不靠改旧代码
OCP 的落地依赖抽象。Java 中最直接的方式就是用接口或抽象类定义契约,让具体行为由子类或实现类提供。
- 典型场景:支付模块支持微信、支付宝、银联。定义 PaymentProcessor 接口,每个渠道写一个实现类(WechatPayment、AlipayPayment),主流程只依赖接口,新增渠道只需加新类+配置,不动原有逻辑
- 避免“伪开闭”:不要在已有 if-else 或 switch 中不断加 case,那是修改而非扩展
里氏替换原则:子类能安全替代父类出现的位置
不是“能编译通过就行”,而是运行时行为不破坏原有逻辑。Java 中违反 LSP 常见于重写父类方法时改变约定(比如父类方法声明不抛异常,子类却 throw RuntimeException;或父类返回非 null,子类返回 null)。
- 检查点:子类重写方法时,输入参数范围不能比父类更窄(如父类接受 Object,子类不该限定为 String);返回值类型不能比父类更宽;异常类型不能比父类更多
- 实用建议:优先用组合代替继承;若必须继承,父类尽量用 abstract class 或 interface,避免具体父类暴露太多可被重写的细节
接口隔离原则 + 依赖倒置 + 迪米特法则:协同降低耦合
这三条常一起起作用:
-
ISP:别让一个接口包罗万象。比如 UserApi 接口不应同时含
login()、exportReport()、sendSms()。拆成 LoginService、ReportService、SmsService,调用方只依赖所需接口 - DIP:高层模块(如 Controller)不依赖低层模块(如 MySQLUtil),都依赖抽象(如 UserRepository 接口)。Spring 的 @Autowired 注入接口正是此原则的体现
-
LOD:一个类只跟“直接朋友”通信。比如 OrderService 要查用户地址,不应写
order.getUser().getAddress().getProvince(),而应让 User 提供getFullAddress()方法,或由 OrderService 通过 UserRepository 查地址
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











