设计模式6大原则详细对比(含场景举例)

一. 6大原则速查对比

原则 核心概念 一句话记忆 违反的典型症状
单一职责 类/模块只负责一个功能领域 专人专事 一个类修改理由太多
开闭原则 扩展新功能时不改原有代码 添新不改旧 每加需求都要改旧类
里氏替换 子类必须能完全替代父类 换子不报错 子类重写后行为异常
依赖倒置 依赖抽象接口而非具体实现 面向接口 代码里全是new具体类
接口隔离 大接口拆分为小接口 接口瘦身 实现类有很多空方法
迪米特法则 只与直接合作对象交互 别管闲事 链式调用a.b.c.d()

原则关系图

复制代码
        ┌─────────────┐
        │   开闭原则   │  ← 终极目标:灵活扩展
        │  (顶层设计)  │
        └──────┬──────┘
               │
    ┌─────────┼─────────┐
    ▼         ▼         ▼
┌───────┐ ┌───────┐ ┌───────┐
│ 单一职责│ │ 里氏替换│ │ 依赖倒置│  ← 三大支撑
│ (内聚) │ │ (继承) │ │ (耦合) │
└───────┘ └───────┘ └───┬───┘
                        │
                    ┌───┴───┐
                    ▼       ▼
                ┌───────┐ ┌───────┐
                │ 接口隔离│ │ 迪米特法则│  ← 具体手段
                │ (接口) │ │ (交互) │
                └───────┘ └───────┘

二. 使用场景与实例

1. 单一职责原则 (SRP)

维度 内容
触发场景 一个类代码超过300行;修改时要改多个地方
典型应用 分层架构(Controller/Service/DAO分离)
生活类比 餐厅分工:服务员点菜、厨师做菜、收银结账

实例:电商订单系统

  • ❌ 错误:OrderManager 处理订单+支付+物流+发邮件

  • ✅ 正确:OrderService + PaymentService + LogisticsService + NotificationService


2. 开闭原则 (OCP)

维度 内容
触发场景 业务规则频繁变化;需要支持多种算法/策略
典型应用 策略模式、插件架构、规则引擎
生活类比 手机APP:更新功能不用换手机,装新APP即可

实例:促销活动系统

场景 实现方式
双11满减 新增Double11Strategy
618折扣 新增Discount618Strategy
会员价 新增MemberPriceStrategy
共同点 都实现PromotionStrategy接口,原有代码零修改

3. 里氏替换原则 (LSP)

维度 内容
触发场景 使用继承关系时;多态调用时
典型应用 集合框架、日志框架(可替换实现)
生活类比 USB接口:U盘、鼠标、键盘都能插,电脑不用区分

实例:权限系统

  • ❌ 错误:AdminUser extends User,但AdminUser禁用了普通用户的某些功能

  • ✅ 正确:UserAdmin都实现Principal接口,各自完整实现,互不干扰


4. 依赖倒置原则 (DIP)

维度 内容
触发场景 需要切换底层实现;需要单元测试
典型应用 Spring依赖注入、Repository模式、Mock测试
生活类比 电源插座:电器依赖插座接口,不依赖具体电厂

实例:数据访问层

层级 依赖关系
业务层 ← 依赖 UserRepository 接口
接口层 UserRepository 定义方法
实现层 MySQLUserRepository / MongoUserRepository / RedisUserRepository

切换数据库:改配置即可,业务代码不动


5. 接口隔离原则 (ISP)

维度 内容
触发场景 接口方法太多;不同实现者需求不同
典型应用 驱动程序接口、回调接口拆分
生活类比 Swiss军刀 vs 专用工具箱:专业场景用专用工具

实例:打印机驱动

  • ❌ 错误接口:Printer 包含打印+扫描+传真+复印

  • ✅ 拆分后:

    • Printable → 普通打印机实现

    • Scannable → 扫描仪实现

    • Faxable → 传真机实现

    • Copiable → 复合机实现多个接口


6. 迪米特法则 (LoD)

维度 内容
触发场景 对象间调用链过长;需要降低耦合度
典型应用 外观模式、中介者模式、DTO封装
生活类比 办事找窗口:不直接找后台科室,由窗口统一协调

实例:电商下单流程

  • ❌ 违反:OrderController → 调OrderService → 调InventoryService → 调WarehouseService → 调StockDao

  • ✅ 遵守:OrderController 只调 OrderService,库存检查由OrderService内部协调,对外隐藏细节


三. 综合决策表

遇到这个问题 使用这个原则 典型解决方案
类太大,改不动 SRP 拆分成多个小类
加功能要改旧代码 OCP 抽象策略+工厂模式
继承后行为异常 LSP 用组合代替继承
换组件要改很多代码 DIP 依赖注入+接口
实现接口要写空方法 ISP 拆分大接口
调用链太长,调试困难 LoD 外观模式/封装内部

一句话总结

SRP 管"分工",OCP 管"扩展",LSP 管"继承",DIP 管"依赖",ISP 管"接口",LoD 管"交互" ------ 六者合力,实现高内聚、低耦合的设计目标。

相关推荐
leeyi6 小时前
两个 Agent 怎么协作:Host-Worker 模式(第91篇-E77)
设计模式·agent·ai编程
AI人工智能+电脑小能手1 天前
大白话说Java设计模式-26-策略模式(业务实战篇)
java·spring·设计模式·策略模式·支付系统·算法切换
星火10241 天前
【Groovy翻译-进阶篇】Groovy 中的设计模式
后端·设计模式·groovy
AI人工智能+电脑小能手1 天前
大白话说Java设计模式-27-策略模式(源码剖析篇)
java·spring·设计模式·策略模式·源码分析·事务管理·comparator
SL_staff1 天前
风控规则如何从硬编码解耦?我们在 JVS-Rules 中的实践与思考
java·spring boot·设计模式
小此方1 天前
Linux加餐(一):藏在Linux中的设计模式(一)策略模式与日志
linux·设计模式·策略模式
To_OC2 天前
从一行入口代码啃透 NestJS:工厂模式、装饰器和依赖注入是怎么串起来的
后端·设计模式·nestjs
东方小月2 天前
从零开发一个 Coding Agent(十二):实现版本化 JSONL 与真实 CLI 入口
前端·设计模式·前端框架
程序员贺加贝2 天前
轻制造SaaS的生产闭环建模-BOM工单领料报工质检与入库
java·设计模式·架构
嘟嘟07172 天前
SDD 规范驱动开发:从 vibe coding 崩盘到"两次创造"
设计模式·代码规范·vibecoding