当前位置: 首页 > news >正文

架构设计模式七大原则

一、为什么你必须先懂「原则」,再谈「模式」?

很多小伙伴一上来就背 23 种设计模式,结果越学越晕。

其实 所有设计模式都围着七大原则转——把它们吃透,模式只是信手拈来的招式。

二、七大原则,一条一条拆给你看!

① 单一职责原则(SRP)

一句话:一个类只做一件事

颜色加粗重点:如果类名里出现 “And”、“Or”,八成已经违背 SRP。

修改前(反面教材)

class UserServiceAndReport {void register() { /* 注册逻辑 */ }void exportPDF() { /* 导出报表逻辑 */ }
}

修改后(符合 SRP)

// 只负责用户注册
class UserService {void register(User user) { /* 注册逻辑 */ }
}// 只负责报表导出
class ReportService {void exportPDF(User user) { /* 导出报表逻辑 */ }
}

注解

  1. 把 注册 和 报表 拆到两个类,职责单一。

  2. 修改注册逻辑时,不会误伤报表功能,风险降低

  3. 单元测试粒度更细,定位 bug 事半功倍

② 开闭原则(OCP)

一句话:对扩展开放,对修改关闭

颜色加粗重点:新增功能靠 “加代码”,而不是 “改旧代码”

场景:订单折扣系统
// 抽象策略
interface DiscountStrategy {BigDecimal apply(BigDecimal price);
}// 新需求:双十一折扣
class DoubleElevenDiscount implements DiscountStrategy {public BigDecimal apply(BigDecimal price) {return price.multiply(new BigDecimal("0.8"));}
}// 使用方
class OrderService {BigDecimal pay(BigDecimal price, DiscountStrategy strategy) {return strategy.apply(price);}
}

注解

  1. 新增 DoubleElevenDiscount 时,完全不动 OrderService

  2. 所有折扣策略实现同一接口,扩展点清晰

  3. 遵循 OCP,减少回归测试成本

③ 里氏替换原则(LSP)

一句话:子类必须能无缝替换父类

颜色加粗重点:别把正方形硬塞进长方形的模子。

// 定义接口
interface Shape {int area();
}// 长方形
class Rectangle implements Shape {int width, height;public int area() { return width * height; }
}// 正方形(保证 LSP)
class Square implements Shape {int side;public int area() { return side * side; }
}

注解

  1. 正方形 不继承长方形,避免 setWidth 时破坏高度。

  2. 只实现 Shape 接口,任何 Shape 都能被统一调用

  3. 满足 LSP,消除运行时类型检查的尴尬

④ 接口隔离原则(ISP)

一句话:客户端不依赖它用不到的方法

颜色加粗重点:胖接口 = 胖 bug 源。

拆分前
interface Machine {void print();void scan();void fax();
}

拆分后

interface Printer { void print(); }
interface Scanner { void scan(); }
interface Fax { void fax(); }class AllInOne implements Printer, Scanner, Fax {/* 真正实现 */
}

注解

  1. 老式打印机只实现 Printer不必空实现 scan/fax

  2. 接口粒度变小,降低实现类的心智负担

  3. 遵循 ISP,提高代码可维护性

⑤ 依赖倒置原则(DIP)

一句话:高层模块不依赖低层,二者都依赖抽象

颜色加粗重点:面向接口编程,而不是面向实现。

示例:通知系统

// 抽象
interface Notifier {void send(String msg);
}// 低层实现
class EmailNotifier implements Notifier {public void send(String msg) { /* 发邮件 */ }
}// 高层业务
class OrderService {private final Notifier notifier; // 依赖抽象OrderService(Notifier n) { this.notifier = n; }void finishOrder() { notifier.send("订单完成"); }
}

注解

  1. OrderService 只认 Notifier不关心是邮件还是短信

  2. 想换短信通知?只需新增 SmsNotifier零修改高层

  3. 完美体现 DIP,系统松耦合

⑥ 迪米特法则(LoD)

一句话:只和直接朋友说话

颜色加粗重点:链式调用 a.getB().getC().do() 是大忌。

反例

class Wallet {public Money money;
}
class Person {public Wallet wallet;
}
// 客户端
person.getWallet().money.reduce(100);

正例

class Person {private Wallet wallet;public void pay(int amount) {wallet.pay(amount);}
}
// 客户端
person.pay(100);

注解

  1. 客户端只认识 Person完全不知道 Wallet 的存在

  2. 降低耦合,类内部变化不影响外部调用

  3. 遵循 LoD,代码更易读、更安全

⑦ 合成复用原则(CRP)

一句话:优先组合,而非继承

颜色加粗重点:继承是“亲儿子”,组合是“干儿子”,后者更灵活。

继承 VS 组合

// 继承 —— 紧耦合
class Bird extends Flyable { }// 组合 —— 松耦合
class Bird {private FlyBehavior flyBehavior; // 组合void fly() { flyBehavior.fly(); }
}

注解

  1. 组合让 Bird 在运行时动态切换飞行策略

  2. 不会陷入“类爆炸”的继承泥潭。

  3. 体现 CRP,系统扩展性 max

总结

单一职责   -> 拆!
开闭原则   -> 加!
里氏替换   -> 换!
接口隔离   -> 瘦!
依赖倒置   -> 抽象!
迪米特     -> 少说话!
合成复用   -> 组合!

背口诀:“拆加换瘦抽象少说话,组合优先”

http://www.dtcms.com/a/354550.html

相关文章:

  • 如何将iPhone上的隐藏照片传输到电脑
  • 零基础开发应用:cpolar+Appsmith平民化方案
  • AbpVnext 阿里云ssl证书多个生产环境自动更新
  • 观远BI仪表板智能洞察场景实战:如何破解门店销售、渠道转化与经营分析难题
  • 用React写一个技能冷却的案例,关于节流
  • C++《哈希表》
  • Day16_【机器学习常见术语】
  • Qt自定义聊天消息控件ChatMessage:初步实现仿微信聊天界面
  • Python 数据分析学习笔记:Pandas 逻辑运算
  • 97、23种设计模式之桥接模式(6/23)
  • 鸿蒙Harmony-从零开始构建类似于安卓GreenDao的ORM数据库(四)
  • attention is all u need
  • npm install --global @dcloudio/uni-cli 时安装失败
  • 【lucene】如何评测一款分析器Analyzer
  • CP1-1-用户管理MyUser
  • jQuery 从入门到实践:基础语法、事件与元素操作全解析
  • 通过vs code配置spring boot+maven项目
  • vxetable数据导出
  • GaussDB 数据库架构师修炼(十八) SQL执行引擎-概述
  • 【爬虫】通过模拟鼠标点击和键盘操作抓取网页数据
  • 算法 --- 二分
  • 【深度学习新浪潮】显著性检测最新研究进展(2022-2025)
  • LeetCode 刷题【55. 跳跃游戏】
  • 用 PyTorch 搭建 CNN 实现 MNIST 手写数字识别
  • 如何开发线下陪玩儿小程序
  • 【图像处理基石】DCT在图像处理中的应用及实现
  • natapp 内网穿透
  • 【iOS】Masnory自动布局的简单学习
  • 图算法详解:最短路径、拓扑排序与关键路径
  • 使用 httpsok 工具全面排查网站安全配置