设计模式总结

设计模式是软件开发中经过总结和验证的、解决特定场景下常见问题的最佳实践,它能提升代码的可复用性、可维护性、可读性和扩展性。根据目的和应用场景,设计模式主要分为创建型模式结构型模式行为型模式三大类,以下是各类模式的核心总结及对应UML图:

一、创建型模式

创建型模式聚焦于对象的创建过程,封装对象创建的细节,降低创建逻辑与业务逻辑的耦合,让程序在创建对象时更灵活。

1. 单例模式(Singleton)

  • 核心意图:保证一个类仅有一个实例,并提供一个全局访问点。

  • 适用场景:配置管理、日志记录器、数据库连接池等需唯一实例的场景。

  • 实现要点:私有化构造方法,通过静态方法/属性返回唯一实例;需考虑线程安全(如懒汉式加锁、饿汉式提前初始化)、序列化/反序列化破坏单例的问题。

  • 优缺点:优点是节省资源、全局统一访问;缺点是违背单一职责,扩展困难,可能引发并发问题(未妥善处理时)。

UML类图

2. 工厂方法模式(Factory Method)

  • 核心意图:定义创建对象的接口,让子类决定实例化哪个类,将对象创建延迟到子类。

  • 适用场景:产品种类可扩展,创建逻辑需隔离的场景(如日志框架支持不同日志输出类型)。

  • 实现要点:抽象工厂类定义创建方法,具体工厂类实现该方法创建对应产品。

  • 优缺点:优点是符合开闭原则,解耦产品创建与使用;缺点是新增产品需新增工厂类,类数量增多。

UML类图

3. 抽象工厂模式(Abstract Factory)

  • 核心意图:提供一个创建一系列相关或相互依赖对象的接口,无需指定具体类。

  • 适用场景:需创建一套“产品族”(如操作系统+UI组件组合、数据库+驱动组合)的场景。

  • 实现要点:抽象工厂定义多个产品创建方法,具体工厂实现所有方法,产出对应产品族。

  • 优缺点:优点是保证产品族一致性,隔离具体产品;缺点是新增产品族需修改抽象工厂,违背开闭原则。

UML类图

4. 建造者模式(Builder)

  • 核心意图:将复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。

  • 适用场景:对象属性多、构造逻辑复杂(如建造汽车、生成复杂文档)。

  • 实现要点:建造者类封装构建步骤,指挥者类控制构建流程,产品类表示最终对象。

  • 优缺点:优点是解耦构建与表示,灵活控制构建过程;缺点是产品属性固定时冗余,类数量增加。

UML类图

5. 原型模式(Prototype)

  • 核心意图:通过复制现有实例(原型)创建新对象,避免重复初始化开销。

  • 适用场景:对象创建成本高(如数据库查询后的数据对象)、需批量创建相似对象的场景。

  • 实现要点:实现克隆接口(浅克隆/深克隆),通过原型对象复制生成新对象。

  • 优缺点:优点是简化创建过程,提升性能;缺点是深克隆需处理复杂引用关系。

UML类图

二、结构型模式

结构型模式关注类和对象的组合方式,通过合理的结构设计,提升代码的灵活性和复用性,解决类/对象间的耦合与扩展问题。

1. 适配器模式(Adapter)

  • 核心意图:将一个类的接口转换成客户希望的另一个接口,让不兼容的类可以协同工作。

  • 适用场景:集成第三方库、复用现有类但接口不匹配、新旧系统对接。

  • 实现要点:类适配器(继承适配者)、对象适配器(组合适配者)、接口适配器(默认空实现)。

  • 优缺点:优点是复用现有代码,解耦接口与实现;缺点是增加额外类,复杂场景可能导致适配链过长。

UML类图(对象适配器)

2. 装饰器模式(Decorator)

  • 核心意图:动态地给一个对象添加一些额外的职责,比继承更灵活。

  • 适用场景:需扩展对象功能,且功能可组合(如IO流、日志增强、权限叠加)。

  • 实现要点:装饰器类与被装饰类实现同一接口,持有被装饰对象引用,重写方法并增强逻辑。

  • 优缺点:优点是灵活扩展,符合开闭原则;缺点是多层装饰会增加代码复杂度。

UML类图

3. 代理模式(Proxy)

  • 核心意图:为其他对象提供一种代理以控制对这个对象的访问。

  • 适用场景:远程代理(RPC)、虚拟代理(懒加载)、保护代理(权限控制)、日志代理(监控)。

  • 实现要点:静态代理(手动编写代理类)、动态代理(JDK动态代理、CGLIB),代理类与目标类实现同一接口/继承目标类。

  • 优缺点:优点是隔离目标对象,增强访问控制;缺点是增加代理层,可能降低性能。

UML类图(静态代理)

4. 外观模式(Facade)

  • 核心意图:为子系统中的一组接口提供一个一致的入口,简化子系统的使用。

  • 适用场景:复杂系统(如电商下单:库存、支付、物流子系统)、对外提供统一API。

  • 实现要点:外观类封装子系统交互逻辑,对外暴露简单接口。

  • 优缺点:优点是降低使用复杂度,解耦客户端与子系统;缺点是外观类可能成为“上帝类”,耦合过多逻辑。

UML类图

5. 桥接模式(Bridge)

  • 核心意图:将抽象部分与它的实现部分分离,使它们都可以独立地变化。

  • 适用场景:多维度变化的场景(如“形状+颜色”、“操作系统+文件系统”)。

  • 实现要点:抽象类持有实现类引用,抽象与实现分层,各自独立扩展。

  • 优缺点:优点是解耦抽象与实现,符合开闭原则;缺点是增加代码复杂度,理解成本高。

UML类图

6. 组合模式(Composite)

  • 核心意图:将对象组合成树形结构以表示“部分-整体”的层次结构,统一对待单个对象和组合对象。

  • 适用场景:树形结构场景(如菜单、文件目录、组织架构)。

  • 实现要点:抽象组件类定义公共方法,叶子节点类表示单个对象,组合节点类包含子组件集合。

  • 优缺点:优点是统一访问单个/组合对象,简化客户端逻辑;缺点是设计复杂,限制类型时需额外判断。

UML类图

7. 享元模式(Flyweight)

  • 核心意图:运用共享技术有效地支持大量细粒度的对象,减少内存占用。

  • 适用场景:大量相似对象(如池化资源、字符常量池、游戏角色)。

  • 实现要点:区分内部状态(共享)和外部状态(不共享),享元工厂管理共享对象池。

  • 优缺点:优点是减少内存消耗,提升性能;缺点是增加系统复杂度,需处理外部状态。

UML类图

三、行为型模式

行为型模式关注对象间的交互和职责分配,优化对象的通信方式和行为逻辑,提升代码的协作性和可扩展性。

1. 观察者模式(Observer)

  • 核心意图:定义对象间的一对多依赖,当一个对象状态改变时,所有依赖它的对象都得到通知并自动更新。

  • 适用场景:事件驱动、发布-订阅(如GUI事件、消息通知、数据监听)。

  • 实现要点:主题(被观察者)维护观察者列表,提供注册/移除/通知方法;观察者实现更新方法。

  • 优缺点:优点是解耦主题与观察者,支持广播通知;缺点是观察者过多时通知效率低,可能引发循环依赖。

UML类图

2. 策略模式(Strategy)

  • 核心意图:定义一系列算法,将每个算法封装起来,使它们可以互相替换,且算法的变化不影响使用算法的客户。

  • 适用场景:多种算法可选(如排序算法、支付方式、优惠计算)。

  • 实现要点:策略接口定义算法方法,具体策略类实现算法,上下文类持有策略引用并调用。

  • 优缺点:优点是算法可灵活切换,符合开闭原则;缺点是客户端需了解所有策略,策略过多时类数量增加。

UML类图

3. 模板方法模式(Template Method)

  • 核心意图:定义一个操作中的算法骨架,将一些步骤延迟到子类中,子类不改变算法结构即可重定义某些步骤。

  • 适用场景:流程固定但步骤实现可变(如框架初始化、报表生成、测试流程)。

  • 实现要点:抽象父类定义模板方法(固定流程)和抽象方法(可变步骤),子类实现抽象方法。

  • 优缺点:优点是复用流程代码,控制扩展点;缺点是模板方法过多时父类复杂,子类受限。

UML类图

4. 迭代器模式(Iterator)

  • 核心意图:提供一种方法顺序访问一个聚合对象中的各个元素,而不暴露其内部表示。

  • 适用场景:遍历集合(如列表、集合、树),统一遍历接口。

  • 实现要点:迭代器接口定义遍历方法(next、hasNext),聚合类提供获取迭代器的方法。

  • 优缺点:优点是统一遍历接口,解耦聚合与遍历;缺点是简单遍历场景下增加冗余类。

UML类图

5. 命令模式(Command)

  • 核心意图:将请求封装成对象,以便使用不同的请求、队列或日志来参数化其他对象,支持撤销/重做操作。

  • 适用场景:请求解耦(如GUI按钮、事务操作、任务队列)。

  • 实现要点:命令接口定义执行方法,具体命令类封装接收者和动作,调用者触发命令执行。

  • 优缺点:优点是解耦请求者与接收者,支持命令组合、撤销;缺点是类数量增加,简单场景冗余。

UML类图

6. 责任链模式(Chain of Responsibility)

  • 核心意图:为请求创建一个接收者对象的链,使多个对象都有机会处理请求,避免请求发送者与接收者耦合。

  • 适用场景:请求需多节点处理(如权限审批、日志分级、异常处理链)。

  • 实现要点:处理者接口定义处理方法,每个处理者持有下一个处理者引用,自行处理或转发请求。

  • 优缺点:优点是解耦请求与处理,动态调整责任链;缺点是请求可能无人处理,调试复杂。

UML类图

7. 状态模式(State)

  • 核心意图:允许对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。

  • 适用场景:对象行为依赖状态(如订单状态、电梯状态、游戏角色状态)。

  • 实现要点:状态接口定义行为方法,具体状态类实现对应行为,上下文类持有当前状态并委托状态处理。

  • 优缺点:优点是状态逻辑集中管理,避免大量if-else;缺点是状态多时有大量状态类。

UML类图

8. 备忘录模式(Memento)

  • 核心意图:在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便后续恢复。

  • 适用场景:撤销操作(如编辑器、游戏存档、事务回滚)。

  • 实现要点:备忘录类存储状态,原发器创建/恢复备忘录,管理者管理备忘录。

  • 优缺点:优点是支持状态回滚,封装状态;缺点是消耗内存(大量备忘录)。

UML类图

9. 中介者模式(Mediator)

  • 核心意图:用一个中介对象来封装一系列的对象交互,使各对象不需要显式地相互引用,降低耦合。

  • 适用场景:多对象复杂交互(如聊天室、GUI组件交互、分布式系统协调)。

  • 实现要点:中介者接口定义交互方法,具体中介者封装对象间交互,同事类通过中介者通信。

  • 优缺点:优点是解耦对象间交互,简化维护;缺点是中介者可能成为“上帝类”,复杂度高。

UML类图

10. 解释器模式(Interpreter)

  • 核心意图:给定一个语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。

  • 适用场景:简单语法解析(如表达式计算、配置解析、自定义脚本)。

  • 实现要点:抽象表达式定义解释方法,终结符/非终结符表达式实现具体逻辑,环境类存储上下文。

  • 优缺点:优点是灵活扩展语法;缺点是语法复杂时类数量爆炸,效率低。

UML类图

四、设计模式核心原则

所有设计模式均围绕SOLID原则展开,是设计模式的底层逻辑:

  1. 单一职责原则(SRP):一个类只负责一个职责,降低耦合。

  2. 开闭原则(OCP):对扩展开放,对修改关闭,通过抽象/接口实现。

  3. 里氏替换原则(LSP):子类可替换父类且不影响程序正确性。

  4. 接口隔离原则(ISP):拆分臃肿接口,提供最小化专用接口。

  5. 依赖倒置原则(DIP):依赖抽象而非具体实现,降低耦合。

五、设计模式使用建议

  1. 不要过度设计:仅在问题重复出现、需复用/扩展时使用,避免为了用模式而用模式。

  2. 优先复用现有框架:多数框架已内置设计模式(如Spring的单例、代理,MyBatis的工厂、装饰器),无需重复实现。

  3. 结合场景选择:如创建对象选创建型,扩展功能选装饰器/策略,解耦交互选观察者/中介者。

  4. 理解本质而非形式:模式的核心是解决问题的思路,而非固定代码结构。

设计模式是经验的沉淀,掌握其思想能让代码更贴合“高内聚、低耦合”的软件设计目标,提升系统的可维护性和扩展性。