# 设计模式：原则与三大类模式详解

> 发布时间: 2026-08-02 18:27

# 设计模式

## 原则

### 总纲

* 开闭原则：一个软件实体，如类、模块、函数应该对**扩展开放，修改封闭**

### 六大原则

1. 单一职责原则
   * 一个类应该只有一个发生变化的原因
2. 里氏替换原则
   * 所有使用基类的地方必须能透明的使用其子类对象
3. 依赖倒置原则
   1. 上层模块不应依赖于底层模块，他们都应该依赖于抽象
   2. 抽象不应依赖于细节，细节应依赖于抽象
4. 接口隔离原则
   1. 客户端不应该依赖于他不需要的接口
   2. 类间的依赖关系应该建立在最小的接口上
5. 迪米特法则（最少知道原则）
   * 只与你的朋友交谈，不和陌生人说话
   * 出现为成员变量、方法参数、方法返回值的类为直接朋友
6. 合成复用原则
   * 尽量使用对象的组合/聚合，而不是继承达到软件复用的目的

> 合成复用原则的重要性：通常类的复用分为继承复用和合成复用两种。继承复用虽然简单易实现，但破坏类的封装性（白箱复用）、子类与父类耦合度高、复用灵活性低；组合/聚合复用维持封装性（黑箱复用）、耦合度低、可以在运行时动态复用。

## 创建型

### 工厂模式（Factory）

* 通过继承产品的基类，来实现产品的多态，通过封装工厂的产品创建函数来实现制造的唯一接口
* 存在的问题：只能生成继承于 Product 的产品，当要生成不同类型的产品时相形见绌

```c++
enum EM_ProductType
{
	Product1,
	Product2,
};
class Product
{

};

class Product1:public Product
{

};
class Product2:public Product
{

};
class Factory
{
	Product* CreateProduct(EM_ProductType eType)
	{
		switch(eType)
		{
			case Product1:
				return new Product1();
			case Product2:
				return new Product2();
		}
	}
};

int main(int argc,char** argv)
{
	Factory factory;
	Product* pro1 = factory.CreateProduct(Product1);
	Product* pro2 = factory.CreateProduct(Product2);
}
```

```plantuml
class Factory{
	CreatePrudct()
}
class Product{
	Desc
}
class Product1{
	1111111111
}
class Product2{
	2222222222
}
Product1 --|> Product
Product2 --|> Product
Factory ..> Product1
Factory ..> Product2
```

### 抽象工厂模式（AbstractFactory）

* 以工厂模式为基础，进一步对工厂进行了抽象

```plantuml
Abstract AbstractFactory{
	Create1()
	Create2()
}
class Factory1{
	Create1()
	Create2()
}
class Factory2{
	Create1()
	Create2()
}
class Product_1{
	Desc
}
class Product_1_1{
	1111111111
}
class Product_1_2{
	2222222222
}

class Product_2{
	Desc
}
class Product_2_1{
	1111111111
}
class Product_2_2{
	2222222222
}
Factory1 .u.|> AbstractFactory
Factory2 .u.|> AbstractFactory
Product_1_1 --|> Product_1
Product_1_2 --|> Product_1
Product_2_1 --|> Product_2
Product_2_2 --|> Product_2
Factory1 ..> Product_1_1
Factory1 ..> Product_1_2
Factory2 ..> Product_2_1
Factory2 ..> Product_2_2
```

### 单例模式（Singleton）

* 一次创建多次使用，分为懒汉模式和饿汉模式

### 建造者模式（Builder）

* 如同生产线一样，一个 builder 关注于产品的每一道工序，通过修改每一道工序，实现输出产品的不同

```plantuml
class Factory{
	GetCar()
}
class Color{

}
class Red{

}
class Yellow{

}

class Shape{

}
class Big{

}
class Small{

}
class Car{
	GetColor()
	GetShape()
}
Red -l-|> Color
Yellow -l-|> Color
Big -l-|> Shape
Small -l-|> Shape
Factory --> Color
Color --> Shape
Shape-->Car
```

### 原型模式（Prototype）

* 通过 Clone 创建新数据进行使用，保证原有数据不被污染

## 结构型

### 适配器模式（Adapter）

* 将一个类的接口转换成客户希望的另一个接口，使原本由于接口不兼容的类可以一起工作

```plantuml
class Target
{
	Opt()
}

class Adapter
{
	Opt()
}

class Adaptee
{
	TryOpt()
}

Target <|-- Adapter
Adapter --> Adaptee
```

### 装饰器模式（Decorator）

* 动态给一个对象添加一些额外职责

```plantuml
class Move
{

}
class Run
{

}

class ActDecorator
{
	Move()
	Run()
}

Move o-- ActDecorator
Run o-- ActDecorator
```

### 代理模式（Proxy）

* 为其他对象提供一种代理以控制对这个对象的访问

```plantuml
class RealSubject
{

}

class Proxy
{

}

class Subject
{

}

Proxy --> RealSubject
Subject --> Proxy
```

### 外观模式（Facade）

* 为子系统中的一组接口提供一个一致的界面，使这个子系统更加容易使用

```plantuml
class KTV
{
	Light
	Door
	..
	OpenKTV
	CloseKTV
}

class Light
{
	On
	Off
}

class Door
{
	On
	Off
}

KTV::OpenKTV -* Light::On
KTV::OpenKTV -* Door::On
KTV::CloseKTV -l-* Light::Off
KTV::CloseKTV -l-* Door::Off
```

### 桥接模式（Bridge）

* 将抽象部分与其实现部分分离，使它们可以独立变化

```plantuml
class Soldier
{
	Action()
}

Abstract ActionBridge
{
	Action()
}

class MoveAction
{
	Action()
}

class AtkAction
{
	Action()
}

Soldier *- ActionBridge

ActionBridge <|.. MoveAction
ActionBridge <|.. AtkAction
```

### 组合模式（Composite）

* 将对象组合成树型结构，以表示"部分-整体"的层次结构，使用户对单个对象和组合对象的使用具有一致性，如 Unity 的 Component

### 享元模式（FlyWeight）

* 运用共享技术有效的支持大量细粒度的对象，对象池

## 行为型

### 策略模式（Strategy）

* 定义一系列算法，把它们个个封装起来，并且使他们可以相互替换。此模式使得算法可以独立于使用他们的客户而变化

### 模板方法模式（Template）

* 定义一个操作中的算法骨架，而将一些步骤延迟到子类，使子类可以不改变一个算法的结构即可重新定义该算法（如模板类）

### 观察者模式（Observer）

* 定义对象间的一种一对多的依赖关系，当一个对象状态发生改变时，所有依赖于它的对象都得到通知并自动更新（事件与委托）

### 迭代子模式（Iterator）

* 提供一种方法顺序访问一个聚合对象中的各个元素，且不需要暴露该对象的内部表示

### 责任链模式（Chain of Responsibility）

* 使多个对象都有机会处理请求，从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链，并沿着这条链传递该请求，直到有一个对象处理它为止

### 命令模式（Command）

* 将一个请求封装为一个对象，从而使得可以用不同的请求对客户进行参数化；对请求排队或记录请求日志，以及支持可撤销的操作

### 备忘录模式（Memento）

* 在不破坏封装性的前提下捕获一个对象的内部状态，并在对象之外保存这个状态，这样以后就可以将对象恢复到原先保存的状态

### 状态模式（State）

* 允许一个对象在其内部状态改变时改变它的行为

### 访问者模式（Visitor）

* 表示一个作用于某对象结构中的各元素的操作。它允许在不改变各元素的类的前提下定义作用于这些元素的新操作

### 中介者模式（Mediator）

* 用一个中介对象来封装一系列对象交互。中介者使各对象不需要显示的相互引用，从而使其耦合松散，而且可以独立地改变它们之间的交互

### 解释器模式（Interpreter）

* 给定一个语言，定义它的文法的一种表示，并定义一个解释器，这个解释器使用该表示来解释语言中的句子