设计模式规则
# 设计模式规则
# 一、设计原则(必须遵循)
- 单一职责:一个类只负责一个职责。
- 接口隔离:客户端不依赖不需要的接口;类之间保持最小依赖。
- 依赖倒置:高层与底层都依赖抽象;面向接口编程,不依赖具体实现。
- 里氏替换:子类继承父类时,尽量不修改父类方法行为。
- 开闭原则:对扩展开放,对修改关闭。
- 迪米特法则:只与直接朋友通信;通过接口隐藏实现,降低耦合。
- 合成复用:优先使用组合/聚合,少用继承;把变化点独立出来,针对接口编程,追求松耦合。
# 二、模式选型速查
| 场景 | 推荐模式 |
|---|---|
| 全局唯一实例(工具类、连接池、配置) | 单例(推荐:双重检查、静态内部类、枚举) |
| 批量/多态创建对象,与调用方解耦 | 简单工厂 / 工厂方法 / 抽象工厂 |
| 通过拷贝创建对象,避免重复构造 | 原型(注意深拷贝与浅拷贝) |
| 复杂对象分步构建,步骤固定 | 建造者 |
| 接口不兼容、需包装成目标接口 | 适配器(优先对象适配器,少用类适配器) |
| 抽象与实现分离、多维度扩展 | 桥接 |
| 动态给对象增加职责、可层层包装 | 装饰者 |
| 树形结构、部分-整体一致对待 | 组合 |
| 为子系统提供统一入口、简化调用 | 外观 |
| 大量细粒度对象共享状态以节省资源 | 享元 |
| 控制访问、延迟加载、增强职责 | 代理 |
| 固定流程、部分步骤子类实现 | 模板方法 |
| 请求封装成对象、支持撤销/队列 | 命令 |
| 算法族可替换、消除大量 if-else | 策略 |
| 多级审批、过滤器链 | 职责链 |
| 对象状态改变驱动行为变化 | 状态 |
| 一对多通知、事件驱动 | 观察者 |
# 三、单例模式
- 禁止:懒汉式仅同步代码块(无法保证线程安全)。
- 推荐:双重检查 + volatile、静态内部类、或枚举;需要懒加载时用双重检查或静态内部类。
- 构造器必须私有;对外只提供
getInstance()等统一入口。
# 四、工厂与创建对象
- 将“创建哪种对象”从业务代码中抽离到工厂;通过工厂方法或抽象工厂扩展产品族,而不是在调用处写
switch/if。 - 简单工厂:适合类型少、变化少;工厂方法:子类决定实例化哪个类;抽象工厂:一组相关产品一起创建。
# 五、结构型模式
- 适配器:优先组合被适配对象(对象适配器),符合合成复用原则;类适配器需继承,灵活性差。
- 装饰者:与代理区别在于装饰者侧重增强职责,可多层包装;保持与组件同一抽象(同接口或父类)。
- 桥接:把抽象与实现分离到不同层次,用组合连接,避免用继承堆砌维度。
# 六、行为型模式
- 策略:把易变算法抽成策略接口,用组合注入;避免多重 if-else,符合开闭原则。
- 模板方法:骨架在父类,步骤用
final固定,可变步骤用抽象方法或钩子;子类只实现差异部分。 - 职责链:处理者持有下一处理者引用,不能处理则传递;注意链长与性能,避免超长链。
- 状态:每个状态封装成类,状态切换委托给状态对象,避免大段 if-else,便于增删状态。
# 七、通用注意
- 先满足七大原则,再考虑具体模式;避免为用模式而用模式。
- 优先“针对接口编程”“组合优于继承”“把变化点独立出来”。
- 写新功能时优先扩展(新类、新实现),少改已有类;发现重复创建或复杂构造时考虑工厂/建造者/原型。