1. UML (Unified Modeling Language)
Structure of UML (USBIE)

- 用户视图(User):用户角度的系统目标
- 结构视图(Structural):静态结构(类、包、对象)
- 行为视图(Behavioral):动态行为(对象交互)
- 实现视图(Implementation):文件分布
- 环境视图(Environmental):硬件设备分布
2. Principle of OO Programmingc
SOLID (给例子问违反了哪个)+CL
Single Responsibility Principle (每个类只能有一个责任)
- Each class should have only one responsibility, meaning it should do one thing and do that thing well.
Open Closed Principle (向扩展开放,向更改关闭)
- Software components should be open for extension but closed for modification.
Liskov Substitution Principle (子类型必须能够完全替换其父类型!)
- Subtypes must be substitutable for their base types without having to alter the base type.
Interface Segregation Principle (使用接口的对象可以自由选择使用的内容)(接口应小而专一,避免“胖接口”)
- Clients should not be forced to depend on properties and methods that they do not use.
Dependency Inversion Principle (高层模块与底层模块分离,使它们都依赖于抽象,而不是具体实现)
- High-level modules should not depend on low-level modules. Both should depend on abstractions.
- Abstractions should not depend on details. Details should depend on abstractions.
Composite Reuse Principle
- 定义:优先使用组合/聚合,而不是继承来达到复用的目的。
- 优点:
- 组合更灵活,支持运行时动态行为
- 继承是“白盒复用”,组合是“黑盒复用”
- 示例:
House类中包含Room对象,而不是继承Room。
Law of Demeter(最少知识原则)
- 定义:一个对象应当对其他对象有尽可能少的了解。
- 核心思想:降低耦合,只与直接朋友通信。
- 实现方式:引入中介类(Controller)来协调对象之间的交互。
- 示例:在表单类与DAO类之间引入
Controller类,减少直接依赖。
3. Overview of DP
模式的基本组成:
- 上下文(Context):使用模式的前提条件
- 问题(Problem):需要处理的目标问题
- 解决方案(Solution):如何解决问题
模式的一般要素:
- 模式名称(Pattern Name)
- 问题(Problem):何时使用该模式
- 解决方案(Solution):如何实现模式思想
- 效果(Consequences):优缺点分析
分类方式:
按目的分类:
- 创建型模式(Creational):用于创建对象
- 结构型模式(Structural):组织多个对象形成高效结构
- 行为型模式(Behavioral):描述类与对象间的交互和职责分配

设计模式的优点(Surfeb)
- 经验总结 (Summary of experiences):汇集多位专家经验,以标准化形式供开发者使用
- 通用语言(Universal language):提供通用术语,便于开发者沟通和理解设计概念
- 促进重用(Reuse successful designs and architectures):使人们能更轻松方便地重用成功的设计和架构
- 提高灵活性 (make design solution more Flexible):使设计解决方案更加灵活且易于修改
- 提升效率 (enhance development Efficiency):提供经过验证的开发范式,提高软件开发效率和软件质量
- 辅助学习 (assists Beginners):帮助初学者深入理解面向对象概念,提升软件设计能力和代码质量
4. Simple Factory (18-19.6)
定义
- 简单工厂模式,也称为静态工厂方法模式。
- 属于类创建型模式。
- 核心:定义一个工厂类,根据传入的不同参数,返回不同类的实例。这些被创建的实例通常具有共同的父类或接口。
意图
- 封装创建逻辑:在不向客户端暴露实例化逻辑的情况下创建对象。(符合open-close原则的思想,但对扩展不支持)
- 面向接口编程:通过一个共同的接口来引用所创建的对象。(符合Dependency Inversion原则)
结构
简单工厂模式包含三个核心角色:
| 角色 | 描述 | 示例(电视机工厂) |
|---|---|---|
| Factory(工厂) | 负责创建所有具体产品的实例。它包含核心的创建逻辑。 | TVFactory |
| Product(抽象产品) | 所有具体产品类的父类,定义了产品的公共接口。 | TV |
| ConcreteProduct(具体产品) | 工厂类创建的目标,实现了抽象产品接口。 | HaierTV, HisenseTV |

优点
- 解耦:客户端与具体产品类解耦。
- 客户端简单:客户端无需知道具体类名,只需传入参数。
- 便于管理:可以通过配置文件(如XML)来管理参数和具体类的映射关系,无需修改代码即可替换产品。
缺点
- 违反开闭原则:这是最严重的缺点。当需要增加新的产品时,必须修改工厂类的源代码(例如,在
switch或if-else语句中增加新的分支)。 - 工厂职责过重:工厂类集中了所有产品的创建逻辑,一旦出错,整个系统受影响。
- 系统复杂度增加:引入了额外的工厂类。
- 静态方法限制:通常使用静态工厂方法,这导致工厂类无法通过继承来扩展行为。
5. Factory Pattern
Virtual Constructor (虚拟构造器) or Polymorphic Factory (多态工厂)
定义
- 工厂方法模式,也称为虚拟构造器或多态工厂。
- 属于类创建型模式。
- 核心:定义一个用于创建对象的接口,但让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
意图
- 定义创建接口:定义一个用于创建对象的接口。
- 子类决定实例化:将实际创建对象的工作推迟到子类中完成。
- 面向接口编程:通过共同的接口来引用新创建的对象。
结构
工厂方法模式包含四个核心角色:
| 角色 | 描述 | 示例(电视机工厂) |
|---|---|---|
| Product(抽象产品) | 定义产品的接口。 | TV |
| ConcreteProduct(具体产品) | 实现抽象产品接口。 | HaierTV, HisenseTV |
| Factory(抽象工厂) | 声明工厂方法,返回一个抽象产品类型的对象。 | TVFactory |
| ConcreteFactory(具体工厂) | 重写工厂方法,返回一个具体产品实例。 | HaierTVFactory, HisenseTVFactory |

工作流程
- 客户端依赖于抽象工厂 (
TVFactory)。 - 在运行时,客户端获得一个具体工厂 (如
HaierTVFactory) 的实例。 - 客户端调用工厂的
factoryMethod()(如produceTV())。 - 具体工厂创建并返回对应的具体产品 (如
HaierTV)。 - 客户端通过抽象产品接口 (
TV) 使用该对象。
与简单工厂模式的对比
| 特性 | 简单工厂模式 | 工厂方法模式 |
|---|---|---|
| 工厂角色 | 一个具体的类,包含所有创建逻辑。 | 一个抽象接口和多个具体实现类。 |
| 扩展性 | 违反开闭原则。新增产品必须修改工厂类源代码。 | 符合开闭原则。新增产品只需添加新的工厂类。 |
| 复杂度 | 结构简单,类少。 | 结构更复杂,类的数量成对增加。 |
| 职责 | 工厂类职责过重,是“万能”的。 | 职责分解,每个具体工厂只负责一种产品。 |
6. Abstract Factory
定义
- 抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
- 核心思想是处理 “产品族” 的创建。
关键概念:产品等级结构与产品族
- 产品等级结构:即产品的抽象与它的具体实现构成的继承结构。例如:
电视机(抽象)与海尔电视机、TCL电视机(具体)。 - 产品族:指位于不同产品等级结构中,但功能相关联的一组产品,它们通常由同一个工厂生产。例如:
海尔工厂生产的海尔电视机、海尔空调、海尔冰箱就构成一个产品族。
结构
抽象工厂模式包含四个核心角色:
| 角色 | 描述 | 示例(电器工厂) |
|---|---|---|
| AbstractFactory(抽象工厂) | 声明一组用于创建一族产品的方法。 | EFactory |
| ConcreteFactory(具体工厂) | 实现抽象工厂的接口,创建属于特定产品族的具体产品。 | HaierFactory, TCLFactory |
| AbstractProduct(抽象产品) | 为每种产品声明接口。 | Television, AirConditioner |
| ConcreteProduct(具体产品) | 定义具体工厂生产的具体产品对象,实现抽象产品接口。 | HaierTelevision, TCLTelevision, HaierAirConditioner, TCLAirConditioner |

与工厂方法模式的对比
这是理解抽象工厂模式的关键:
| 维度 | 工厂方法模式 | 抽象工厂模式 |
|---|---|---|
| 核心维度 | 一维:只关注一个产品等级结构(如:电视机)。 | 二维:关注多个产品等级结构构成的产品族(如:电视机 + 空调)。 |
| 创建目标 | 创建一种产品。 | 创建一族相关的产品。 |
| 工厂职责 | 一个具体工厂只负责创建一个具体产品。 | 一个具体工厂负责创建一个产品族的所有产品。 |
| 适用场景 | 系统只有一个产品等级结构,或不需要关心产品之间的约束。 | 系统有多个产品等级结构,且产品之间有关联,需要保证一起使用同一家族的产品。 |
简单比喻:
- 工厂方法:一个专营店(如海尔电视专营店、TCL电视专营店)。
- 抽象工厂:一个品牌旗舰店(如海尔旗舰店,里面卖电视、空调、冰箱;TCL旗舰店,里面也卖电视、空调、冰箱)。
优点
- 分离具体类:客户端与具体产品的创建过程分离。
- 保证产品族一致性:确保客户端始终使用同一产品族的对象。这是其最大优势。
- 符合开闭原则(对产品族):增加一个新的产品族(如新增一个
HisenseFactory)非常方便,无需修改现有代码。
缺点
- 难以支持新的产品种类:这是其最大缺点。如果要在所有产品族中增加一个新的产品种类(如在
EFactory中增加produceRefrigerator()方法),就需要修改抽象工厂接口及其所有具体工厂子类,这违反了开闭原则。
public interface AbstractFactory{
public AbstractProductA createProductA();
public AbstractProductB createProductB();
}
public interface AbstractProductA{
//
}
public class ProductA1 implements AbstractProductA{
system.out.print("ProductA1:: a product is built!");
}
public class ConcreteFactory1 implements AbstractFactory{
public AbstractProductA createProductA(){
return new ProductA1();
}
public AbstractProductB createProductB(){
return new ProductB1;
}
}
简单工厂、工厂模式和抽象工厂 (18-19.7)
The following code uses the ( ) pattern:
A. Simple Factory
B. Factory Method
C. Abstract Factory
D. No design patterns are used
public abstract class ExchangeMethod {
public abstract void process ( );
}
public class DigitalCurrency extends ExchangeMethod{
public void process( ){...}
}
public class CreditCard extends ExchangeMethod{
public void process( ){...}
}
...
public class Factory{
public static ExchangeMethod createProduct(String type){
switch(type){
case"DigitalCurrency":
return new DigitalCurrency( );break;
case"CreditCard":
return new CreditCard( );break;
...
}
}
}
三种工厂模式核心区别总结
为了清晰区分,我们从四个维度来对比:
| 维度 | 简单工厂 | 工厂方法 | 抽象工厂 |
|---|---|---|---|
| 工厂角色 | 一个具体类,包含所有创建逻辑 | 一个抽象接口/类 + 多个具体工厂子类 | 一个抽象接口/类 + 多个具体工厂子类 |
| 创建方式 | 静态方法,根据参数创建不同产品 | 每个具体工厂只创建一种具体产品 | 每个具体工厂创建一族相关产品 |
| 扩展性 | 违反开闭原则 新增产品必须修改工厂类 | 符合开闭原则 新增产品时,添加新的具体工厂即可 | 对产品族符合开闭原则 新增产品族容易,新增产品种类困难 |
| 结构复杂度 | 简单,类少 | 较复杂,类成对增加(一个产品一个工厂) | 最复杂,涉及多个产品等级结构 |
一句话概括核心思想
- 简单工厂:一个万能工厂,根据客户的要求(参数)生产所有产品。
- 工厂方法:每个产品都有自己的专属工厂(子类),工厂之间是平行的。
- 抽象工厂:每个品牌(产品族)有自己的综合工厂,这个工厂能生产该品牌下的所有产品(如电视、空调、冰箱)。
如何快速识别
- 看到
static工厂方法 +switch/if+ 参数决定对象 → 简单工厂 - 看到工厂是接口/抽象类 + 每个具体产品对应一个具体工厂子类 → 工厂方法
- 看到一个具体工厂能创建多个不同类的产品(这些产品是相关的)→ 抽象工厂
7. Builder
定义
- 建造者模式:将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。
- 它采用分步骤的方式来构建一个复杂对象。用户只需指定复杂对象的类型和内容,无需知道内部的具体构建细节。
- 属于对象创建型模式。
意图
- 封装性:客户端不需要知道复杂对象的内部组成部分和组装方式。
- 过程性:关注于一步步地构建一个复杂对象。不同的建造者定义了不同的创建过程。
结构
建造者模式包含四个核心角色:
| 角色 | 描述 | 示例(KFC套餐) |
|---|---|---|
| Builder(抽象建造者) | 为创建一个产品对象的各个部件指定抽象接口。 | MealBuilder |
| ConcreteBuilder(具体建造者) | 实现Builder的接口,定义并明确它所创建的复杂对象的各个部件。提供检索产品的接口。 | SubMealBuilderA, SubMealBuilderB |
| Director(指挥者) | 构建一个使用Builder接口的对象。它安排复杂对象的构建次序。 | KFCWaiter |
| Product(产品) | 被构建的复杂对象。包含多个组成部分。 | Meal |

优点
- 良好的封装性:客户端不必知道产品内部组成的细节。
- 构建过程独立:将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
- 易于扩展:符合开闭原则。要增加新的具体建造者非常方便,无需修改现有代码。
- 精细控制:可以更精细地控制产品的创建过程。
缺点
- 产品共性要求高:所创建的产品需要有较多的共同点,如果产品之间差异非常大,则不适合使用建造者模式。
- 系统复杂性增加:如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,使得系统变得庞大。
适用场景
- 需要生成的产品对象有复杂的内部结构(包含多个成员变量)。
- 需要生成的产品对象的属性相互依赖,需要指定其生成顺序。
- 需要将对象的创建过程(算法)与它的组成部分解耦。
- 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品。
核心思想总结
建造者模式的精髓在于 “流程固定,部件可变”。
- 指挥者 负责 “流程固定”(先放主食,再放饮料)。
- 具体建造者 负责 “部件可变”(主食是汉堡还是鸡肉卷,饮料是可乐还是果汁)。
这使得它在创建需要多个步骤、且步骤相同但结果不同的复杂对象时,非常有用。它是对工厂模式(关注整体实例化)的一种补充,更侧重于对象的组装过程。
8.5 Prototype
定义
- 原型模式:使用原型实例指定要创建对象的种类,然后通过复制这个原型来创建新的对象。
- 属于对象创建型模式。
- 核心思想:自我复制。
意图
通过复制一个原型对象来创建多个与其相同的对象。
- 适用于创建过程复杂、需要频繁实例化的对象。
- 客户端不需要知道对象创建的细节,只需要知道原型对象。
结构
原型模式包含三个核心角色:
| 角色 | 描述 | 示例(邮件复制) |
|---|---|---|
| Prototype(抽象原型) | 声明克隆方法的接口。 | Cloneable 接口 |
| ConcretePrototype(具体原型) | 实现克隆方法,返回自身的一个副本。 | Email 类 |
| Client(客户端) | 让一个原型克隆自身从而创建一个新对象。 | 使用Email的客户端 |

浅克隆(Shallow Clone) vs 深克隆(Deep Clone)
| 类型 | 特点 | 图示说明 |
|---|---|---|
| 浅克隆 | 只复制对象本身和其值类型成员,引用类型成员只复制引用(指向同一个对象)。 | 原型对象和克隆对象共享附件 |
| 深克隆 | 复制对象本身以及所有引用类型成员指向的对象。 | 原型对象和克隆对象各有自己的附件副本 |
优点
- 简化创建过程:通过复制现有实例来创建新实例,效率高。
- 良好的扩展性:可以动态添加产品类。
- 简化创建结构:不需要专门的工厂类,产品自己完成克隆。
- 可以保存对象状态:通过深克隆可以保存对象状态,便于实现撤销操作。
缺点
- 违反开闭原则:需要为每个类提供克隆方法,修改现有类时需要修改源代码。
- 深克隆实现复杂:实现深克隆需要编写复杂的代码。
- 对继承关系不友好:如果原型类处于继承层次中,可能需要在所有层次上都正确实现克隆。
适用场景
- 创建新对象成本较高时(如对象需要从数据库加载大量数据)。
- 系统需要保存对象状态,但对象状态变化很小。
- 需要避免使用分层次的工厂类来创建分层次的对象。
- 类的实例只有几个不同状态组合时,建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便。
典型应用
- 邮件复制:复制包含附件、收件人、主题等复杂内容的邮件对象。
- 图形编辑器:复制复杂的图形对象。
- 游戏开发:复制游戏角色、道具等。
- 配置对象:复制系统配置对象。
8. Singlton
定义
- 单例模式:确保一个类只有一个实例,并提供一个全局访问点来获取这个实例。这个类被称为单例类。
三个核心特征
- 一个类在内存中只有一个实例
- 该实例必须由这个类自行创建
- 该实例必须能够被整个系统访问
结构
单例模式的结构非常简单,只包含一个角色:
| 角色 | 描述 |
|---|---|
| Singleton(单例) | 负责创建和管理自己的唯一实例,并提供全局访问点 |

1. 懒汉式(Lazy Singleton)
- 特点:实例在第一次被调用时才创建
- 优点:避免了不必要的资源消耗
- 缺点:需要考虑多线程安全问题(基础实现非线程安全)
public class Singleton {
private static Singleton instance = null;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) { // 多线程环境下不安全
instance = new Singleton();
}
return instance;
}
}
2. 饿汉式(Eager Singleton)
- 特点:实例在类加载时就创建
- 优点:实现简单,天生线程安全
- 缺点:如果实例一直未被使用,会造成资源浪费
public class EagerSingleton {
private static final EagerSingleton instance = new EagerSingleton();
private EagerSingleton() {}
public static EagerSingleton getInstance() {
return instance; // 直接返回预先创建好的实例
}
}
优点
- 严格控制实例:提供了对唯一实例的受控访问
- 节约资源:只存在一个对象,可以节约系统资源,提高系统性能
- 允许可变数量的实例:可以扩展为多例模式
缺点
- 难以扩展:由于没有抽象层,单例类的扩展有很大困难
- 职责过重:单例类既提供了业务方法,又负责创建自身实例,某种程度上违背了”单一职责原则”
- 状态丢失:在一些依赖于垃圾回收机制的环境中,如果单例对象长时间不被使用,可能会被回收,导致状态丢失
五、适用场景
- 系统只需要一个实例对象,或者因为资源消耗太大而只允许创建一个对象。例如:
- 任务管理器
- 打印池
- 数据库连接池
- 应用配置类
- 客户调用类的单个实例只允许使用一个公共访问点,除了该公共访问点,不能通过其他途径访问该实例
Adapter
定义
- 适配器模式:将一个类的接口转换成客户希望的另外一个接口。
- 使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
- 可以作为类结构型模式和对象结构型模式。
意图
- 解决不兼容问题:就像电源适配器解决220V电压与20V笔记本电脑的不兼容一样。
- 软件场景:方法名不一致、参数不匹配、接口规范不同等。
结构
适配器模式包含三个核心角色:
| 角色 | 描述 | 示例(机器人模仿狗) |
|---|---|---|
| Target abstract class(目标抽象类) | 定义客户要使用的特定领域的接口。 | Robot |
| Adapter(适配器) | 调用另一个接口,作为一个转换器。 | DogAdapter |
| Adaptee(适配者) | 被适配的角色,包含需要使用的接口。 | Dog |
| Class Adapter | Object Adapter |
|---|---|
![]() | ![]() |
优点
- 解耦目标与适配者
- 提高类的复用性
- 灵活性和扩展性好
- 类适配器:可以重写适配者的方法
- 对象适配器:可以适配多个不同的适配者
缺点
- 类适配器:
- 一次只能适配一个适配者
- 不能适配final类
- 对象适配器:重写适配者的方法比较麻烦
Bridge
定义
- 桥接模式:将抽象部分与它的实现部分分离,使它们都可以独立地变化。
- 用抽象关联关系取代传统的多层继承关系。
- 将类之间的静态继承关系转换为动态的对象组合关系。
核心动机:解决多维度变化
- 蜡笔问题:颜色和型号两个维度耦合在一起,需要准备
颜色数 × 型号数个类(如:3种型号 × 5种颜色 = 15个类)。 - 毛笔方案:颜色和型号分离,只需要
颜色数 + 型号数个类(如:3种型号 + 5种颜色 = 8个类)。
结构
桥接模式包含四个核心角色:
| 角色 | 描述 | 示例(画笔) |
|---|---|---|
| Abstraction(抽象类) | 定义抽象接口,维护一个实现类对象的引用。 | Pen |
| RefinedAbstraction(扩充抽象类) | 扩充由抽象类定义的接口。 | SmallPen, MiddlePen, BigPen |
| Implementor(实现类接口) | 定义实现类的接口。 | Color |
| ConcreteImplementor(具体实现类) | 实现实现类接口。 | Red, Green, Blue, White, Black |

优点
- 分离抽象与实现:真正的解耦,两者可以独立变化。
- 取代多层继承:极大地减少了子类的数量。
- 提高扩展性:扩展任意一个维度都无需修改现有系统,符合开闭原则。
- 细节对客户透明:客户无需关心实现的细节。
缺点
- 增加理解难度:要求开发者在设计之初就基于抽象层进行思考。
- 识别维度困难:正确识别系统中两个独立变化的维度并不容易。
适用场景
- 一个类存在两个(或多个)独立变化的维度,且这些维度都需要进行扩展。
- 不希望使用继承,或者因为多层继承导致系统类的个数急剧增加。
- 需要在多个对象间共享实现,但同时要求客户端代码不知道这一点。
Composite
核心定义
- 将对象组合成树形结构以表示”部分-整体”的层次结构。组合模式使得用户对单个对象(叶子对象)和组合对象(容器对象)的使用具有一致性。
意图
- 当程序需要处理树形数据结构,并且需要统一对待树枝(容器)和树叶(叶子)节点时。
结构
| 角色 | 描述 | 示例(文件系统) |
|---|---|---|
| Component(抽象组件) | 定义组合中对象的统一接口,声明访问和管理子组件的方法。 | AbstractElement |
| Leaf(叶子组件) | 表示组合中的叶子节点,没有子节点,实现组件接口的业务方法。 | File |
| Composite(容器组件) | 表示组合中的容器节点,包含子组件集合,实现管理子组件的方法,并在业务方法中递归调用子组件。 | Folder |
两种实现变体
| 透明组合模式 | 安全组合模式 | |
|---|---|---|
| 特点 | 在抽象组件中声明所有管理子对象的方法 | 只在容器组件中声明管理子对象的方法 |
| 优点 | 客户端可以完全一致地对待所有对象 | 编译期类型安全 |
| 缺点 | 不够安全,叶子对象可能抛出不支持的操作异常 | 客户端需要区分叶子与容器,失去透明性 |
优点:
- 简化客户端代码,统一处理逻辑
- 符合开闭原则,易于添加新组件
- 清晰地定义了层次复杂的对象
缺点:
- 设计较复杂,需要正确区分叶子与容器
- 难以在容器中限制组件类型
适用场景
根据课件总结的适用情况:
- 处理具有层次结构的系统(文件系统、组织架构等)
- 希望忽略整体与部分的差异,统一对待
- 系统需要处理树形结构数据
- 需要灵活扩展新的组件类型
Decorate
定义
装饰模式是一种结构型设计模式,它动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活。
核心意图
- 动态扩展 - 在不改变对象自身的情况下,动态地添加功能
- 替代继承 - 提供继承之外的另一种扩展功能的方式
- 透明增强 - 客户端无需知道对象是否被装饰,可以像使用原始对象一样使用装饰后的对象
结构总结
| 角色 | 描述 | 示例(变形金刚) |
|---|---|---|
| Component(抽象组件) | 定义对象的统一接口,可以被动态添加职责。 | Transformer |
| ConcreteComponent(具体组件) | 定义具体的对象,将要被添加职责的原始对象。 | Car |
| Decorator(抽象装饰类) | 维护一个指向Component对象的引用,并定义与Component一致的接口。 | TransformerDecorator |
| ConcreteDecorator(具体装饰类) | 向组件添加具体的职责,在调用原始方法前后执行附加行为。 | RobotDecorator, AirplaneDecorator |

优点:
- 比继承更灵活,避免类层次过深
- 符合开闭原则,易于扩展
- 可以动态添加/撤销功能
缺点:
- 产生大量小对象,增加系统复杂度
- 调试困难,多层装饰时排查问题麻烦
Facade(object structural pattern)
定义
外观模式是一种结构型设计模式,它为子系统中的一组接口提供一个统一的高层接口,使得子系统更容易使用。
意图
- 简化接口 - 为复杂子系统提供简单统一的入口
- 解耦客户端 - 将客户端与子系统的复杂实现分离
- 降低依赖 - 减少客户端对子系统内部组件的直接依赖

结构
| 角色 | 描述 | 示例(电器开关) |
|---|---|---|
| Facade(外观类) | 知道哪些子系统负责处理请求,将客户端请求代理给适当的子系统对象 | GeneralSwitchFacade |
| SubSystem(子系统) | 实现子系统的功能,处理外观类指派的任务,子系统之间可以相互交互 | Light, Fan, AirConditioner, Television |
| Client(客户端) | 通过外观接口与子系统交互,无需直接访问子系统 | 开关使用者 |
优点:
- 简化客户端使用,降低学习成本
- 实现客户端与子系统的松耦合
- 符合迪米特法则(最少知识原则)
缺点:
- 如果设计不当,新增子系统需要修改外观类,违反开闭原则
Chain of Responsibility
定义
责任链模式是一种行为型设计模式,它通过给多个对象处理请求的机会,避免请求发送者与接收者耦合。将接收对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
意图
- 解耦发送者与接收者 - 发送者不需要知道具体由哪个接收者处理请求
- 动态组织处理链 - 可以在运行时动态改变处理请求的对象链
- 多对象协作 - 让多个对象都有机会处理请求
结构
| 角色 | 描述 | 示例(请假审批) |
|---|---|---|
| Handler(抽象处理者) | 定义处理请求的接口,维护后继处理者的引用 | Leader |
| ConcreteHandler(具体处理者) | 处理自己负责的请求,可访问后继者,可转发请求 | Director, Manager, GeneralManager |
| Client(客户端) | 创建处理链,向链头的处理者提交请求 | 请假申请系统 |
| Request(请求) | 封装请求信息,在链中传递 | LeaveRequest |

优点:
- 降低耦合度,发送者无需知道具体处理者
- 增强系统灵活性,可动态调整责任链
- 符合开闭原则,新增处理者无需修改现有代码
缺点:
- 请求可能未被处理(链中无合适处理者)
- 调试困难,请求传递路径不明确
- 性能问题,长链可能影响处理速度
Command
定义
命令模式是一种行为型设计模式,它将一个请求封装为一个对象,从而让你可以用不同的请求对客户进行参数化,支持请求的排队、记录日志,以及支持可撤销的操作。
意图
- 请求封装 - 将请求封装成独立的对象
- 解耦调用者与执行者 - 调用者不需要知道具体的执行细节
- 支持事务操作 - 实现请求的排队、日志、撤销等功能
结构
| 角色 | 描述 | 示例(电视遥控器) |
|---|---|---|
| Command(抽象命令) | 声明执行操作的接口 | AbstractCommand |
| ConcreteCommand(具体命令) | 将一个接收者对象绑定于一个动作,实现执行方法 | TVOpenCommand, TVCloseCommand, TVChangeCommand |
| Invoker(调用者) | 要求命令执行请求 | Controller(遥控器) |
| Receiver(接收者) | 知道如何实施与执行一个请求相关的操作 | Television |
| Client(客户端) | 创建具体命令对象并设定其接收者 | 遥控器配置程序 |

优点:
- 降低系统的耦合度,调用者与接收者解耦
- 新的命令可以很容易地加入到系统中
- 可以比较容易地设计一个命令队列和宏命令
- 可以方便地实现请求的撤销和恢复
缺点:
- 使用命令模式可能会导致某些系统有过多的具体命令类
- 增加了系统的复杂性
Iterator
定义
迭代器模式是一种行为型设计模式,它提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。
意图
- 封装遍历逻辑 - 将遍历算法从聚合对象中分离出来
- 统一访问接口 - 为不同的聚合结构提供一致的遍历方式
- 保护内部结构 - 客户端无需了解聚合对象的内部实现细节
结构
| 角色 | 描述 | 示例(电视系统) |
|---|---|---|
| Iterator(抽象迭代器) | 定义访问和遍历元素的接口 | TvIterator |
| ConcreteIterator(具体迭代器) | 实现迭代器接口,跟踪遍历位置 | SkyworthIterator, TCLIterator |
| Aggregate(抽象聚合类) | 定义创建迭代器对象的接口 | Television |
| ConcreteAggregate(具体聚合类) | 实现创建迭代器的接口,返回具体迭代器实例 | SkyworthTelevision, TCLTelevision |
| Client(客户端) | 通过迭代器接口访问聚合对象元素 | 遥控器使用者 |

优点:
- 支持以不同的方式遍历一个聚合对象
- 简化了聚合类的接口
- 在同一个聚合上可以有多个遍历
- 符合开闭原则,易于扩展新的聚合类和迭代器类
缺点:
- 增加系统复杂度,需要成对增加聚合类和迭代器类
- 抽象迭代器的设计难度较大
- 对于简单的聚合对象,使用迭代器可能过度设计
Strategy
定义
策略模式是一种行为型设计模式,它定义了一系列算法,将每个算法封装起来,并使它们可以相互替换。策略模式让算法的变化独立于使用算法的客户端。
意图
- 算法封装 - 将不同的算法封装在独立的策略类中
- 灵活替换 - 客户端可以在运行时动态选择不同的策略
- 消除条件判断 - 避免使用复杂的条件语句来选择算法
结构
| 角色 | 描述 | 示例(排序算法) |
|---|---|---|
| Context(环境类) | 维护对策略对象的引用,可动态切换策略 | ArrayHandler |
| Strategy(抽象策略) | 定义所有支持算法的公共接口 | Sort |
| ConcreteStrategy(具体策略) | 实现抽象策略定义的接口,提供具体算法 | BubbleSort, SelectionSort, InsertionSort |

优点:
- 完美支持开闭原则,易于扩展新算法
- 提供了管理相关算法族的方法
- 可以避免多重条件选择语句
- 提供了算法的复用机制
缺点:
- 客户端必须了解所有策略类的区别
- 会产生很多具体策略类
- 无法同时使用多个策略类·

