架构设计模式七大原则

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

很多小伙伴一上来就背 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。

总结

单一职责 -> 拆!

开闭原则 -> 加!

里氏替换 -> 换!

接口隔离 -> 瘦!

依赖倒置 -> 抽象!

迪米特 -> 少说话!

合成复用 -> 组合!

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

相关推荐
白杨尚青10 分钟前
C++入门篇(十):string(上)——认识string:构造与三大遍历(一条龙讲透operator[]、迭代器、auto、范围for)
java·开发语言·c++·笔记·stl
可乐鸡翅yeah_15 分钟前
hls.js 切换多个视频源,新手开发常见踩坑
开发语言·前端·javascript·ios·ffmpeg·音视频·safari
Tanshu_API君19 分钟前
API 聚合平台选型指南:从参数拆解到生产落地的十个评估维度
开发语言·api
Chen—LSN20 分钟前
C语言——⽂件操作(1)
c语言·开发语言·c++·经验分享·笔记·算法·链表
狗凯之家源码网23 分钟前
PHP 开源 IM 即时通讯系统效果实测与功能展示
开发语言·开源·php
anew___24 分钟前
《从零手写操作系统 (11):文件系统初探——initrd与VFS抽象层》
java·javascript·算法
天天向上29127 分钟前
Spring AI 实战:14 个踩坑记录,其中一个让我的测试全绿但产品是坏的
java·开源
正在走向自律36 分钟前
从只写接口到独立交付前后端,飞算JavaAI能给Java后端工程师多少溢价?
java·springboot·ai编程·全栈开发·java求职·飞算javaai·金九银十
辛苦才能39 分钟前
C++ map/set 深度解析:从关联式容器的本质到 operator[] 的三重身份
开发语言·c++
Chen—LSN1 小时前
C语言——文件操作(2)
c语言·开发语言·c++·经验分享·笔记·算法·c#