设计模式六大原则核心是 “让代码好改、好用、不浪费”,用大白话拆解如下:
1. 单一职责原则:一个类只干一件事
- 核心:每个类 / 模块只负责一个功能,别让它又当 “厨师” 又当 “服务员”。
- 举例:订单类只管订单的创建、查询,付款功能单独放付款类,后续改付款逻辑时,不会影响订单功能。
2. 开放封闭原则:对扩展开放,对修改关闭
- 核心:想加新功能时,别改老代码,而是新增代码(比如加新类、新方法)。
- 举例:原来的系统只支持微信支付,现在要加支付宝支付,不用改已有的微信支付代码,新增一个支付宝支付类就行,避免改坏老功能。
3. 里氏替换原则:子类能无缝替掉父类
- 核心:子类继承父类后,不能破坏父类的原有功能,替换后程序还能正常跑。
- 举例:父类是 “鸟”,有 “飞” 的方法,子类 “鸵鸟” 就不能继承这个父类(因为鸵鸟不会飞),否则用鸵鸟替换鸟时,“飞” 的功能就失效了。
4. 依赖倒置原则:依赖抽象,不依赖具体
- 核心:别直接依赖某个具体的类,而是依赖它的 “接口 / 抽象类”,这样换实现类时更灵活。
- 举例:开车时,你依赖的是 “方向盘” 这个抽象功能(左转、右转),而不是具体的 “宝马方向盘” 或 “奔驰方向盘”,换车时不用重新学怎么开。
5. 接口隔离原则:接口要精简,别搞 “大杂烩”
- 核心:一个接口只包含需要的方法,别把无关的方法都塞进去,避免强迫用户实现用不上的功能。
- 举例:不能搞一个 “万能接口”,又包含支付方法、又包含退款方法、还包含物流方法,应该拆成 “支付接口”“退款接口”,需要哪个就实现哪个。
6. 迪米特法则:只和 “熟人” 说话
- 核心:一个类尽量少了解其他类的细节,只和直接相关的类(比如自己的属性、方法参数、返回值)交互,别越级调用。
- 举例:你想点外卖,直接找外卖平台(熟人)就行,不用去了解商家的后厨怎么做菜、骑手怎么导航,平台会帮你对接,减少依赖。
总结
六大原则本质都是为了 “解耦” 和 “复用”:让代码之间少纠缠,改一个地方不影响其他地方,新增功能时不用大动干戈。
| 设计原则 | 核心大白话 | 生活场景举例 | 反例(违背原则) | 正例(遵循原则) |
|---|---|---|---|---|
| 单一职责原则 | 一个角色只干一件事 | 餐厅运营 | 服务员又点菜、又做菜、又收银,忙中出错还难追责 | 服务员管点菜 / 上菜,厨师管做菜,收银员管收钱,各司其职 |
| 开放封闭原则 | 加功能不改老的,只加新的 | 手机 APP 新增功能 | 原来只有 “聊天” 功能,加 “支付” 时改乱了聊天代码,导致发不了消息 | 新增独立的 “支付模块”,聊天功能原封不动,互不影响 |
| 里氏替换原则 | 子类能无缝替父类,不添乱 | 交通工具出行 | 父类是 “电动车”(能充电、能骑行),子类 “自行车”(不能充电)继承后,用自行车替换电动车时,“充电” 功能失效 | 自行车单独作为独立类,电动车的子类只留 “电动摩托车”(能充电、能骑行),替换后功能正常 |
| 依赖倒置原则 | 依赖 “通用规则”,不依赖 “具体东西” | 上班通勤 | 只依赖 “地铁 3 号线”(具体),一旦 3 号线停运就没法上班 | 依赖 “公共交通”(抽象),3 号线停了能换公交、网约车,灵活应对 |
| 接口隔离原则 | 需求要啥拿啥,不搞 “大礼包” | 健身房办卡 | 强制办 “全能卡”(含健身、游泳、瑜伽、私教),但你只想要健身 | 拆分 “健身卡”“游泳卡”“瑜伽卡”,按需选择,不花冤枉钱 |
| 迪米特法则 | 只和直接相关的人 / 事打交道 | 组织公司活动 | 你想办团建,直接去问场地老板 “能不能布置成游戏风”,还追问老板的供应商是谁、价格多少 | 你只对接行政同事(直接关联方),告诉行政需求,行政去对接场地、供应商,你不用管中间细节 |
首先明确核心结论:23 个设计模式(常说的 21 个是简化版)并非 “属于” 六大原则,而是六大原则的 “落地实现套路” —— 六大原则是 “设计准则 / 思想”,设计模式是 “遵循这些准则的具体解决方案”,就像 “健康饮食” 是原则,“清蒸鱼、水煮菜” 是符合原则的具体吃法。
下面用「大白话 + 对应原则 + 核心场景」拆解 23 个设计模式(覆盖常见 21 个),帮你一眼看懂 “每个模式在解决啥问题、遵循哪些原则”:
先理清核心逻辑
| 维度 | 六大设计原则 | 23 个设计模式 |
|---|---|---|
| 本质 | 设计的 “宪法 / 指导思想” | 遵循 “宪法” 的 “具体办事流程 / 模板” |
| 关系 | 约束设计模式的设计方向 | 把原则落地到代码的 “可复用套路” |
| 举例 | “一个人只干一件事”(单一职责) | “工厂模式” 把 “创建对象” 单独拎出来干,符合单一职责 |
23 个设计模式(21 个核心)分类拆解(通俗版)
设计模式分 3 大类:创建型(造对象)、结构型(拼对象 / 类)、行为型(定交互),每个模式都紧扣至少 1-2 个核心原则:
一、创建型模式(5 个):解决 “对象怎么造” 的问题,核心遵循「单一职责、依赖倒置」
| 设计模式 | 大白话理解 | 核心解决的问题 | 遵循的核心原则 | 生活例子 |
|---|---|---|---|---|
| 单例模式 | 整个程序里只有这一个对象 | 避免重复创建相同对象(比如配置管理器) | 单一职责(只管理自身实例)、开闭原则 | 公司只有一个公章,所有人用同一个,不重复刻 |
| 工厂方法模式 | 专门造某一类对象的 “小工厂” | 不用直接 new,按 “类型” 造对象,解耦创建逻辑 | 依赖倒置(依赖抽象工厂,不依赖具体类)、单一职责 | 奶茶店:水果茶工厂只做水果茶,奶茶工厂只做奶茶 |
| 抽象工厂模式 | 造 “成套对象” 的 “大工厂” | 造一组相关对象(比如 Windows 按钮 + 窗口) | 依赖倒置、开闭原则 | 家电套装:海尔工厂造冰箱 + 洗衣机,美的工厂也造,但风格统一 |
| 建造者模式 | 分步造复杂对象,先拼零件再组装 | 避免复杂对象创建时参数太多、逻辑混乱 | 单一职责(建造者管组装,产品管功能) | 组装电脑:先装 CPU、再装内存、最后装显卡,分步来 |
| 原型模式 | 复制已有对象造新对象 | 避免重复初始化复杂对象(比如大数据对象) | 单一职责(复制逻辑单独封装) | 复印文件:改几个字就能用,不用重新手写全文 |
二、结构型模式(7 个):解决 “对象 / 类怎么组合” 的问题,核心遵循「接口隔离、迪米特、开闭」
| 设计模式 | 大白话理解 | 核心解决的问题 | 遵循的核心原则 | 生活例子 |
|---|---|---|---|---|
| 适配器模式 | 给不兼容的东西加个 “转换器” | 旧接口和新代码不兼容,不用改老代码 | 开闭原则(扩展不修改)、单一职责 | 港版插头插大陆插座,加个转换头就行 |
| 桥接模式 | 把 “变化维度” 拆分开,各自扩展 | 一个类有多个变化维度(比如形状 + 颜色),避免类爆炸 | 单一职责、开闭原则 | 画画:形状(圆 / 方)和颜色(红 / 蓝)分开,想画红圆就组合 “圆 + 红” |
| 装饰器模式 | 给对象 “穿外套”,动态加功能 | 不修改原对象,给它加新功能(比如加日志) | 开闭原则、单一职责 | 手机:原机 + 手机壳 + 贴膜,功能加了但原机没改 |
| 组合模式 | 把 “单个 / 多个对象” 统一对待 | 树形结构(比如菜单 + 子菜单),操作统一 | 单一职责、里氏替换 | 公司组织架构:员工(单个)和部门(多个员工),都算 “组织单元” |
| 外观模式 | 给复杂流程套个 “简单入口” | 多个子系统交互复杂,对外只暴露一个接口 | 迪米特法则(只和外观类打交道)、单一职责 | 点外卖:只在 APP 下单(外观),不用管商家接单、骑手取餐等细节 |
| 享元模式 | 复用 “共享对象”,省内存 | 大量相似对象(比如棋子),复用相同部分 | 单一职责(共享部分单独封装) | 围棋:黑白棋子只造两个对象,所有棋子复用这两个 |
| 代理模式 | 给对象找个 “代言人” | 控制对象访问(比如权限校验、远程调用) | 迪米特法则(只和代理交互)、单一职责 | 租房:找中介(代理)看房,不用直接找房东 |
三、行为型模式(11 个):解决 “对象之间怎么交互” 的问题,核心遵循「里氏替换、依赖倒置、迪米特」
| 设计模式 | 大白话理解 | 核心解决的问题 | 遵循的核心原则 | 生活例子 |
|---|---|---|---|---|
| 模板方法模式 | 定好 “流程框架”,细节自己填 | 多个流程大部分步骤相同,只改个别步骤 | 开闭原则、里氏替换 | 做奶茶:流程都是 “煮茶底→加配料→装杯”,不同奶茶只改配料 |
| 策略模式 | 把 “算法 / 规则” 抽成独立策略 | 多种算法(比如支付方式),可动态切换 | 开闭原则、依赖倒置 | 导航:可选 “步行 / 公交 / 自驾” 策略,一键切换 |
| 命令模式 | 把 “操作” 封装成对象 | 解耦 “发指令的人” 和 “执行指令的人” | 单一职责、迪米特法则 | 点外卖:下单(命令)发给商家,用户不用管商家怎么做菜 |
| 责任链模式 | 多个对象 “接力处理” 请求 | 一个请求可能被多个对象处理,谁能处理谁来 | 迪米特法则(只传给下一个节点)、开闭原则 | 请假审批:普通员工请假→组长→经理→老板,逐级处理 |
| 状态模式 | 把 “状态” 抽成对象,状态变行为变 | 对象行为随状态变(比如电梯:开门 / 关门 / 运行) | 单一职责、开闭原则 | 红绿灯:红灯(停)、绿灯(行)、黄灯(等),状态变行为变 |
| 观察者模式 | 一个对象变,其他对象 “跟着变” | 一对多依赖(比如订阅通知) | 迪米特法则(只通知观察者)、开闭原则 | 关注公众号:公众号发文章,所有关注的人都收到 |
| 中介者模式 | 找个 “中间人” 协调对象交互 | 多个对象互相依赖,交互复杂 | 迪米特法则(只和中介交互)、单一职责 | 微信群:不用单独私聊每个人,发群里(中介)所有人都能看 |
| 迭代器模式 | 统一 “遍历集合” 的方式 | 不同集合(数组 / 链表),遍历方式统一 | 依赖倒置(依赖抽象迭代器)、单一职责 | 翻书:不管是纸质书还是电子书,都按 “下一页” 遍历 |
| 访问者模式 | 给不同对象 “加新操作”,不修改对象 | 对一组对象加新功能,不用改对象本身 | 开闭原则、单一职责 | 体检:医生(访问者)给不同科室的病人做检查,病人不用改自身 |
| 备忘录模式 | 保存对象 “快照”,可回滚 | 保存对象状态,需要时恢复(比如撤销操作) | 单一职责(备忘录只存状态) | 玩游戏:存档→打怪失败→读档恢复状态 |
| 解释器模式 | 定义 “语言规则”,解析表达式 | 处理简单语法 / 表达式(比如计算器) | 单一职责、开闭原则 | 计算器:解析 “1+2*3”,按数学规则计算结果 |
关键总结
- 原则是 “道”,模式是 “术”:六大原则是设计的底层逻辑,23 个模式是针对不同场景(造对象、拼结构、定交互)的落地方法,所有模式都不会违背六大原则,反而都是为了满足这些原则。
- 不用死记,记 “场景”:比如遇到 “想加功能又不想改老代码”,就想到 “装饰器 / 策略 / 开闭原则”;遇到 “对象交互太乱”,就想到 “中介者 / 迪米特法则”。