C++ 23种设计模式
设计模式(Design Patterns)是面向对象软件开发中解决常见问题的可复用方案。本文档涵盖GoF(Gang of Four)提出的23种经典设计模式,使用C++实现,并配有Mermaid类图。
目录
一、创建型模式(Creational Patterns)
- 单例模式(Singleton)
- [工厂方法模式(Factory Method)](#工厂方法模式(Factory Method))
- [抽象工厂模式(Abstract Factory)](#抽象工厂模式(Abstract Factory))
- 建造者模式(Builder)
- 原型模式(Prototype)
二、结构型模式(Structural Patterns)
- 适配器模式(Adapter)
- 桥接模式(Bridge)
- 组合模式(Composite)
- 装饰模式(Decorator)
- 外观模式(Facade)
- 享元模式(Flyweight)
- 代理模式(Proxy)
三、行为型模式(Behavioral Patterns)
- [责任链模式(Chain of Responsibility)](#责任链模式(Chain of Responsibility))
- 命令模式(Command)
- 解释器模式(Interpreter)
- 迭代器模式(Iterator)
- 中介者模式(Mediator)
- 备忘录模式(Memento)
- 观察者模式(Observer)
- 状态模式(State)
- 策略模式(Strategy)
- [模板方法模式(Template Method)](#模板方法模式(Template Method))
- 访问者模式(Visitor)
一、创建型模式(Creational Patterns)
创建型模式关注对象的创建机制,使系统独立于如何创建、组合和表示对象。
1. 单例模式(Singleton)
意图:确保一个类只有一个实例,并提供一个全局访问点。
适用场景:
- 配置管理器、日志记录器、线程池
- 需要全局唯一实例的场景
UML 类图:
唯一实例
Singleton
-static Singleton* instance
-Singleton()
+static Singleton* getInstance()
+doSomething() : void
C++ 实现(线程安全 - C++11):
cpp
#include <iostream>
#include <mutex>
class Singleton {
private:
static Singleton* instance;
static std::mutex mtx;
Singleton() { std::cout << "Singleton 构造" << std::endl; }
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
public:
static Singleton* getInstance() {
if (instance == nullptr) {
std::lock_guard<std::mutex> lock(mtx);
if (instance == nullptr) {
instance = new Singleton();
}
}
return instance;
}
void doSomething() {
std::cout << "Singleton::doSomething() 被调用" << std::endl;
}
};
Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mtx;
int main() {
Singleton* s1 = Singleton::getInstance();
Singleton* s2 = Singleton::getInstance();
std::cout << "s1 == s2: " << (s1 == s2) << std::endl;
return 0;
}
优缺点:
| 优点 | 缺点 |
|---|---|
| 全局唯一实例,节省资源 | 违反单一职责原则 |
| 延迟初始化,按需创建 | 难以进行单元测试 |
| 线程安全(双重检查锁) | 多线程环境需额外处理 |
2. 工厂方法模式(Factory Method)
意图:定义一个用于创建对象的接口,让子类决定实例化哪一个类。
适用场景:
- 当类不知道它必须创建的对象的类时
- 当类希望其子类指定它创建的对象时
UML 类图:
创建
创建
依赖
<<abstract>>
Product
+operation() : void
ConcreteProductA
+operation() : void
ConcreteProductB
+operation() : void
<<abstract>>
Creator
+factoryMethod() : Product
+someOperation() : void
ConcreteCreatorA
+factoryMethod() : Product
ConcreteCreatorB
+factoryMethod() : Product
C++ 实现:
cpp
#include <iostream>
#include <memory>
// 抽象产品
class Product {
public:
virtual ~Product() = default;
virtual void operation() = 0;
};
// 具体产品 A
class ConcreteProductA : public Product {
public:
void operation() override {
std::cout << "ConcreteProductA::operation()" << std::endl;
}
};
// 具体产品 B
class ConcreteProductB : public Product {
public:
void operation() override {
std::cout << "ConcreteProductB::operation()" << std::endl;
}
};
// 抽象创建者
class Creator {
public:
virtual ~Creator() = default;
virtual std::unique_ptr<Product> factoryMethod() = 0;
void someOperation() {
auto product = factoryMethod();
product->operation();
}
};
// 具体创建者 A
class ConcreteCreatorA : public Creator {
public:
std::unique_ptr<Product> factoryMethod() override {
return std::make_unique<ConcreteProductA>();
}
};
// 具体创建者 B
class ConcreteCreatorB : public Creator {
public:
std::unique_ptr<Product> factoryMethod() override {
return std::make_unique<ConcreteProductB>();
}
};
// 使用示例
int main() {
ConcreteCreatorA creatorA;
creatorA.someOperation(); // 输出: ConcreteProductA::operation()
ConcreteCreatorB creatorB;
creatorB.someOperation(); // 输出: ConcreteProductB::operation()
return 0;
}
优缺点:
| 优点 | 缺点 |
|---|---|
| 符合开闭原则 | 每增加一个产品需增加一个工厂类 |
| 解耦创建和使用 | 增加了系统复杂度 |
| 单一职责,创建逻辑集中 | 需要继承体系 |
3. 抽象工厂模式(Abstract Factory)
意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
适用场景:
- 系统需要独立于产品的创建、组合和表示
- 一系列相关的产品对象需要一起使用
- 跨平台UI组件族(Windows/Mac按钮、文本框等)
UML 类图:
创建
创建
创建
创建
<<abstract>>
AbstractFactory
+createProductA() : AbstractProductA
+createProductB() : AbstractProductB
ConcreteFactory1
+createProductA() : AbstractProductA
+createProductB() : AbstractProductB
ConcreteFactory2
+createProductA() : AbstractProductA
+createProductB() : AbstractProductB
<<abstract>>
AbstractProductA
+operationA() : void
ProductA1
+operationA() : void
ProductA2
+operationA() : void
<<abstract>>
AbstractProductB
+operationB() : void
ProductB1
+operationB() : void
ProductB2
+operationB() : void
C++ 实现:
cpp
#include <iostream>
#include <memory>
// 抽象产品 A
class AbstractProductA {
public:
virtual ~AbstractProductA() = default;
virtual void operationA() = 0;
};
// 抽象产品 B
class AbstractProductB {
public:
virtual ~AbstractProductB() = default;
virtual void operationB() = 0;
};
// 具体产品 A1
class ProductA1 : public AbstractProductA {
public:
void operationA() override {
std::cout << "ProductA1::operationA()" << std::endl;
}
};
// 具体产品 A2
class ProductA2 : public AbstractProductA {
public:
void operationA() override {
std::cout << "ProductA2::operationA()" << std::endl;
}
};
// 具体产品 B1
class ProductB1 : public AbstractProductB {
public:
void operationB() override {
std::cout << "ProductB1::operationB()" << std::endl;
}
};
// 具体产品 B2
class ProductB2 : public AbstractProductB {
public:
void operationB() override {
std::cout << "ProductB2::operationB()" << std::endl;
}
};
// 抽象工厂
class AbstractFactory {
public:
virtual ~AbstractFactory() = default;
virtual std::unique_ptr<AbstractProductA> createProductA() = 0;
virtual std::unique_ptr<AbstractProductB> createProductB() = 0;
};
// 具体工厂 1(生产族1产品)
class ConcreteFactory1 : public AbstractFactory {
public:
std::unique_ptr<AbstractProductA> createProductA() override {
return std::make_unique<ProductA1>();
}
std::unique_ptr<AbstractProductB> createProductB() override {
return std::make_unique<ProductB1>();
}
};
// 具体工厂 2(生产族2产品)
class ConcreteFactory2 : public AbstractFactory {
public:
std::unique_ptr<AbstractProductA> createProductA() override {
return std::make_unique<ProductA2>();
}
std::unique_ptr<AbstractProductB> createProductB() override {
return std::make_unique<ProductB2>();
}
};
// 使用示例
void clientCode(AbstractFactory& factory) {
auto productA = factory.createProductA();
auto productB = factory.createProductB();
productA->operationA();
productB->operationB();
}
int main() {
ConcreteFactory1 factory1;
clientCode(factory1); // 输出族1的产品
ConcreteFactory2 factory2;
clientCode(factory2); // 输出族2的产品
return 0;
}
优缺点:
| 优点 | 缺点 |
|---|---|
| 保证产品族的兼容性 | 增加新产品族困难(需修改接口) |
| 隔离具体类的生成 | 系统复杂度增加 |
| 符合开闭原则(新增工厂) | 层次较深,理解成本高 |
4. 建造者模式(Builder)
意图:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
适用场景:
- 创建复杂对象,构建步骤固定但各步骤实现不同
- 构造一个包含多个部件的对象,创建算法应独立于部件
- 生成HTML文档、配置复杂对象、创建游戏角色等
UML 类图:
使用
构建
Director
-builder: Builder
+construct() : void
<<abstract>>
Builder
+buildPartA() : void
+buildPartB() : void
+buildPartC() : void
+getResult() : Product
ConcreteBuilder
-product: Product
+buildPartA() : void
+buildPartB() : void
+buildPartC() : void
+getResult() : Product
Product
+addPart(part) : void
+show() : void
C++ 实现:
cpp
#include <iostream>
#include <string>
#include <vector>
#include <memory>
// 产品
class Product {
private:
std::vector<std::string> parts;
public:
void addPart(const std::string& part) {
parts.push_back(part);
}
void show() const {
std::cout << "产品构建完成,包含以下部件:" << std::endl;
for (const auto& part : parts) {
std::cout << " - " << part << std::endl;
}
}
};
// 抽象建造者
class Builder {
public:
virtual ~Builder() = default;
virtual void buildPartA() = 0;
virtual void buildPartB() = 0;
virtual void buildPartC() = 0;
virtual std::unique_ptr<Product> getResult() = 0;
};
// 具体建造者
class ConcreteBuilder : public Builder {
private:
std::unique_ptr<Product> product;
public:
ConcreteBuilder() : product(std::make_unique<Product>()) {}
void buildPartA() override {
product->addPart("部件A");
}
void buildPartB() override {
product->addPart("部件B");
}
void buildPartC() override {
product->addPart("部件C");
}
std::unique_ptr<Product> getResult() override {
return std::move(product);
}
};
// 指挥者
class Director {
private:
Builder* builder;
public:
void setBuilder(Builder* b) { builder = b; }
void construct() {
builder->buildPartA();
builder->buildPartB();
builder->buildPartC();
}
};
// 使用示例
int main() {
Director director;
ConcreteBuilder builder;
director.setBuilder(&builder);
director.construct();
auto product = builder.getResult();
product->show();
return 0;
}
优缺点:
| 优点 | 缺点 |
|---|---|
| 构造代码与表示代码分离 | 需要创建多个类 |
| 精细控制构建过程 | 产品必须有共同点 |
| 建造者独立,易扩展 | 不适合创建差异很大的产品 |
5. 原型模式(Prototype)
意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
适用场景:
- 类的实例化代价高(如数据库连接、网络请求)
- 系统需要独立于产品的创建、组合和表示
- 避免使用复杂的工厂层次结构
UML 类图:
使用
<<abstract>>
Prototype
+clone() : Prototype
ConcretePrototype1
-field: int
+clone() : Prototype
ConcretePrototype2
-field: string
+clone() : Prototype
Client
+operation() : void
C++ 实现:
cpp
#include <iostream>
#include <string>
#include <memory>
// 抽象原型
class Prototype {
public:
virtual ~Prototype() = default;
virtual std::unique_ptr<Prototype> clone() = 0;
virtual void print() = 0;
};
// 具体原型 1
class ConcretePrototype1 : public Prototype {
private:
int value;
public:
ConcretePrototype1(int v) : value(v) {}
std::unique_ptr<Prototype> clone() override {
return std::make_unique<ConcretePrototype1>(*this);
}
void print() override {
std::cout << "ConcretePrototype1: value = " << value << std::endl;
}
};
// 具体原型 2
class ConcretePrototype2 : public Prototype {
private:
std::string name;
public:
ConcretePrototype2(const std::string& n) : name(n) {}
std::unique_ptr<Prototype> clone() override {
return std::make_unique<ConcretePrototype2>(*this);
}
void print() override {
std::cout << "ConcretePrototype2: name = " << name << std::endl;
}
};
// 使用示例
int main() {
ConcretePrototype1 prototype1(42);
ConcretePrototype2 prototype2("Hello");
// 通过克隆创建新对象
auto clone1 = prototype1.clone();
auto clone2 = prototype2.clone();
clone1->print(); // ConcretePrototype1: value = 42
clone2->print(); // ConcretePrototype2: name = Hello
// 验证深拷贝:修改原对象不影响克隆
return 0;
}
优缺点:
| 优点 | 缺点 |
|---|---|
| 减少子类数量 | 每个原型子类必须实现clone |
| 动态添加/删除产品 | 深拷贝复杂对象可能有循环引用 |
| 比new效率高(复杂对象) | 需要处理好拷贝构造函数 |
二、结构型模式(Structural Patterns)
结构型模式关注类和对象的组合,用于构建更大的结构。
6. 适配器模式(Adapter)
意图:将一个类的接口转换成客户希望的另一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的类可以一起工作。
适用场景:
- 使用第三方库但接口不兼容
- 新旧系统集成
- 数据格式转换
UML 类图:
适配
依赖
<<abstract>>
Target
+request() : void
Adapter
-adaptee: Adaptee
+request() : void
Adaptee
+specificRequest() : void
Client
C++ 实现(对象适配器):
cpp
#include <iostream>
// 目标接口(客户端期望的接口)
class Target {
public:
virtual ~Target() = default;
virtual void request() {
std::cout << "Target::request() 默认实现" << std::endl;
}
};
// 需要适配的类(已有的不兼容接口)
class Adaptee {
public:
void specificRequest() {
std::cout << "Adaptee::specificRequest() 被适配的特殊请求" << std::endl;
}
};
// 适配器(对象适配器 - 使用组合)
class Adapter : public Target {
private:
Adaptee* adaptee;
public:
Adapter(Adaptee* a) : adaptee(a) {}
void request() override {
std::cout << "Adapter 转换调用: ";
adaptee->specificRequest();
}
};
// 使用示例
int main() {
Adaptee adaptee;
Target* target = new Adapter(&adaptee);
target->request(); // 通过Target接口调用Adaptee的功能
delete target;
return 0;
}
优缺点:
| 优点 | 缺点 |
|---|---|
| 复用现有类而无需修改 | 过多适配器使系统复杂 |
| 灵活,可同时适配多个类 | C++中可能需多重继承 |
| 符合开闭原则 | 接口转换有一定性能开销 |
7. 桥接模式(Bridge)
意图:将抽象部分与它的实现部分分离,使它们都可以独立地变化。
适用场景:
- 避免抽象和实现之间的永久绑定
- 抽象和实现都应能通过子类化独立扩展
- 跨平台开发(不同操作系统的窗口实现)
UML 类图:
桥接
Abstraction
-impl: Implementor
+operation() : void
RefinedAbstraction
+operation() : void
<<abstract>>
Implementor
+operationImpl() : void
ConcreteImplementorA
+operationImpl() : void
ConcreteImplementorB
+operationImpl() : void
C++ 实现:
cpp
#include <iostream>
#include <memory>
// 实现接口
class Implementor {
public:
virtual ~Implementor() = default;
virtual void operationImpl() = 0;
};
// 具体实现 A
class ConcreteImplementorA : public Implementor {
public:
void operationImpl() override {
std::cout << "ConcreteImplementorA::operationImpl()" << std::endl;
}
};
// 具体实现 B
class ConcreteImplementorB : public Implementor {
public:
void operationImpl() override {
std::cout << "ConcreteImplementorB::operationImpl()" << std::endl;
}
};
// 抽象类
class Abstraction {
protected:
std::unique_ptr<Implementor> impl;
public:
Abstraction(std::unique_ptr<Implementor> i) : impl(std::move(i)) {}
virtual ~Abstraction() = default;
virtual void operation() {
std::cout << "Abstraction::operation() -> ";
impl->operationImpl();
}
};
// 扩展抽象类
class RefinedAbstraction : public Abstraction {
public:
RefinedAbstraction(std::unique_ptr<Implementor> i) : Abstraction(std::move(i)) {}
void operation() override {
std::cout << "RefinedAbstraction::operation() -> ";
impl->operationImpl();
}
};
// 使用示例
int main() {
auto abstractionA = std::make_unique<Abstraction>(
std::make_unique<ConcreteImplementorA>()
);
abstractionA->operation();
auto refinedB = std::make_unique<RefinedAbstraction>(
std::make_unique<ConcreteImplementorB>()
);
refinedB->operation();
return 0;
}
优缺点:
| 优点 | 缺点 |
|---|---|
| 抽象和实现解耦 | 增加系统复杂度 |
| 符合开闭原则 | 需要正确识别维度 |
| 实现细节对客户端透明 | 设计不当导致类爆炸 |
8. 组合模式(Composite)
意图:将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
适用场景:
- 文件系统(文件和文件夹)
- GUI组件树(窗体、按钮、文本框等)
- 树形菜单结构
UML 类图:
包含
<<abstract>>
Component
+operation() : void
+add(Component*) : void
+remove(Component*) : void
+getChild(int) : Component
Leaf
+operation() : void
Composite
-children: list<Component*>
+operation() : void
+add(Component*) : void
+remove(Component*) : void
+getChild(int) : Component
C++ 实现:
cpp
#include <iostream>
#include <vector>
#include <memory>
// 抽象组件
class Component {
public:
virtual ~Component() = default;
virtual void operation() = 0;
virtual void add(std::unique_ptr<Component>) {
throw std::runtime_error("不支持添加操作");
}
virtual void remove(Component*) {
throw std::runtime_error("不支持移除操作");
}
};
// 叶子节点
class Leaf : public Component {
private:
std::string name;
public:
Leaf(const std::string& n) : name(n) {}
void operation() override {
std::cout << "Leaf [" << name << "] 操作" << std::endl;
}
};
// 组合节点
class Composite : public Component {
private:
std::string name;
std::vector<std::unique_ptr<Component>> children;
public:
Composite(const std::string& n) : name(n) {}
void operation() override {
std::cout << "Composite [" << name << "] 开始操作,包含 "
<< children.size() << " 个子节点:" << std::endl;
for (auto& child : children) {
child->operation();
}
}
void add(std::unique_ptr<Component> component) override {
children.push_back(std::move(component));
}
};
// 使用示例
int main() {
auto root = std::make_unique<Composite>("根节点");
auto leaf1 = std::make_unique<Leaf>("叶子1");
auto leaf2 = std::make_unique<Leaf>("叶子2");
auto subComposite = std::make_unique<Composite>("子组合");
subComposite->add(std::make_unique<Leaf>("叶子3"));
subComposite->add(std::make_unique<Leaf>("叶子4"));
root->add(std::move(leaf1));
root->add(std::move(leaf2));
root->add(std::move(subComposite));
root->operation();
return 0;
}
优缺点:
| 优点 | 缺点 |
|---|---|
| 一致地处理单个对象和组合 | 设计难度高 |
| 容易增加新组件类型 | 限制类型安全(叶子与组合差异) |
| 形成清晰的树形结构 | 违反接口隔离(Leaf也有add/remove) |
9. 装饰模式(Decorator)
意图:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活。
适用场景:
- 动态、透明地给对象添加职责
- 需要可撤销的功能增强
- 不能用继承扩展或继承的类被
final修饰时
UML 类图:
装饰
<<abstract>>
Component
+operation() : void
ConcreteComponent
+operation() : void
Decorator
-component: Component
+operation() : void
ConcreteDecoratorA
+operation() : void
+addedBehavior() : void
ConcreteDecoratorB
+operation() : void
+addedBehavior() : void
C++ 实现:
cpp
#include <iostream>
#include <memory>
#include <string>
// 抽象组件
class Component {
public:
virtual ~Component() = default;
virtual std::string operation() = 0;
};
// 具体组件
class ConcreteComponent : public Component {
public:
std::string operation() override {
return "ConcreteComponent";
}
};
// 抽象装饰器
class Decorator : public Component {
protected:
std::unique_ptr<Component> component;
public:
Decorator(std::unique_ptr<Component> c) : component(std::move(c)) {}
std::string operation() override {
return component->operation();
}
};
// 具体装饰器 A
class ConcreteDecoratorA : public Decorator {
public:
ConcreteDecoratorA(std::unique_ptr<Component> c) : Decorator(std::move(c)) {}
std::string operation() override {
return "ConcreteDecoratorA(" + Decorator::operation() + ")";
}
};
// 具体装饰器 B
class ConcreteDecoratorB : public Decorator {
public:
ConcreteDecoratorB(std::unique_ptr<Component> c) : Decorator(std::move(c)) {}
std::string operation() override {
return "ConcreteDecoratorB[" + Decorator::operation() + "]";
}
};
// 使用示例
int main() {
auto component = std::make_unique<ConcreteComponent>();
std::cout << "原始: " << component->operation() << std::endl;
auto decoratorA = std::make_unique<ConcreteDecoratorA>(std::move(component));
std::cout << "装饰A后: " << decoratorA->operation() << std::endl;
auto decoratorB = std::make_unique<ConcreteDecoratorB>(std::move(decoratorA));
std::cout << "装饰B后: " << decoratorB->operation() << std::endl;
// 输出: ConcreteDecoratorB[ConcreteDecoratorA(ConcreteComponent)]
return 0;
}
优缺点:
| 优点 | 缺点 |
|---|---|
| 比继承更灵活地扩展功能 | 产生大量小对象 |
| 可动态组合装饰器 | 装饰器和组件有区别时复杂 |
| 符合开闭原则 | 多层装饰调试困难 |
10. 外观模式(Facade)
意图:为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,使得子系统更加容易使用。
适用场景:
- 简化复杂子系统的访问
- 为遗留代码提供简单接口
- 构建分层架构的入口点
UML 类图:
Facade
-subsystem1: SubSystem1
-subsystem2: SubSystem2
-subsystem3: SubSystem3
+simpleOperation() : void
+complexOperation() : void
SubSystem1
+operation1() : void
SubSystem2
+operation2() : void
SubSystem3
+operation3() : void
Client
C++ 实现:
cpp
#include <iostream>
// 子系统 1
class SubSystem1 {
public:
void operation1() {
std::cout << "SubSystem1::operation1()" << std::endl;
}
};
// 子系统 2
class SubSystem2 {
public:
void operation2() {
std::cout << "SubSystem2::operation2()" << std::endl;
}
};
// 子系统 3
class SubSystem3 {
public:
void operation3() {
std::cout << "SubSystem3::operation3()" << std::endl;
}
};
// 外观类
class Facade {
private:
SubSystem1 subsystem1;
SubSystem2 subsystem2;
SubSystem3 subsystem3;
public:
void simpleOperation() {
std::cout << "=== 简单操作 ===" << std::endl;
subsystem1.operation1();
}
void complexOperation() {
std::cout << "=== 复杂操作 ===" << std::endl;
subsystem1.operation1();
subsystem2.operation2();
subsystem3.operation3();
}
};
// 使用示例
int main() {
Facade facade;
facade.simpleOperation();
facade.complexOperation();
return 0;
}
优缺点:
| 优点 | 缺点 |
|---|---|
| 简化客户端调用 | 可能成为"上帝对象" |
| 减少客户端与子系统的耦合 | 不符合开闭原则(新增功能需修改) |
| 分层清晰 | 无法限制客户端直接使用子系统 |
11. 享元模式(Flyweight)
意图:运用共享技术有效地支持大量细粒度的对象,减少内存占用。
适用场景:
- 系统中有大量相似对象
- 对象的大部分状态可以外置
- 需要缓冲池的场景(如字符串常量池、字符格式对象)
状态分类:
- 内部状态(Intrinsic State):可共享,不随环境变化
- 外部状态(Extrinsic State):不可共享,随环境变化
UML 类图:
管理
FlyweightFactory
-flyweights: map<string, Flyweight*>
+getFlyweight(key) : Flyweight
<<abstract>>
Flyweight
+operation(extrinsicState) : void
ConcreteFlyweight
-intrinsicState: string
+operation(extrinsicState) : void
UnsharedConcreteFlyweight
-allState: string
+operation(extrinsicState) : void
内部状态可共享
外部状态不共享
C++ 实现:
cpp
#include <iostream>
#include <string>
#include <unordered_map>
#include <memory>
// 享元接口
class Flyweight {
public:
virtual ~Flyweight() = default;
virtual void operation(const std::string& extrinsicState) = 0;
};
// 具体享元(含内部可共享状态)
class ConcreteFlyweight : public Flyweight {
private:
std::string intrinsicState; // 内部状态(可共享)
public:
ConcreteFlyweight(const std::string& state) : intrinsicState(state) {}
void operation(const std::string& extrinsicState) override {
std::cout << "内部状态: " << intrinsicState
<< ", 外部状态: " << extrinsicState << std::endl;
}
};
// 享元工厂
class FlyweightFactory {
private:
std::unordered_map<std::string, std::shared_ptr<Flyweight>> flyweights;
public:
std::shared_ptr<Flyweight> getFlyweight(const std::string& key) {
auto it = flyweights.find(key);
if (it != flyweights.end()) {
std::cout << "复用已有享元: " << key << std::endl;
return it->second;
}
std::cout << "创建新享元: " << key << std::endl;
auto flyweight = std::make_shared<ConcreteFlyweight>(key);
flyweights[key] = flyweight;
return flyweight;
}
int getCount() const { return static_cast<int>(flyweights.size()); }
};
int main() {
FlyweightFactory factory;
factory.getFlyweight("红色")->operation("位置(1,1)");
factory.getFlyweight("蓝色")->operation("位置(2,3)");
factory.getFlyweight("红色")->operation("位置(5,7)");
factory.getFlyweight("绿色")->operation("位置(3,4)");
std::cout << "享元对象总数: " << factory.getCount() << std::endl;
return 0;
}
优缺点:
| 优点 | 缺点 |
|---|---|
| 大幅减少内存占用 | 增加系统复杂度 |
| 提高性能(减少对象创建) | 需要区分内/外部状态 |
| 适合大量相似对象场景 | 外部状态管理复杂 |
12. 代理模式(Proxy)
意图:为其他对象提供一种代理以控制对这个对象的访问。
适用场景:
- 远程代理(访问远程对象)
- 虚拟代理(延迟加载大对象)
- 保护代理(控制访问权限)
- 缓存代理(缓存请求结果)
UML 类图:
代理
依赖
<<abstract>>
Subject
+request() : void
RealSubject
+request() : void
Proxy
-realSubject: RealSubject
+request() : void
Client
C++ 实现(虚拟代理 + 保护代理):
cpp
#include <iostream>
#include <memory>
#include <string>
class Subject {
public:
virtual ~Subject() = default;
virtual void request() = 0;
};
class RealSubject : public Subject {
public:
void request() override {
std::cout << "RealSubject::request() 真实操作" << std::endl;
}
};
// 虚拟代理:延迟初始化
class Proxy : public Subject {
private:
std::unique_ptr<RealSubject> realSubject;
std::string role;
public:
Proxy(const std::string& r) : role(r) {}
void request() override {
if (role != "admin") {
std::cout << "Proxy: 权限不足,拒绝访问" << std::endl;
return;
}
if (!realSubject) {
std::cout << "Proxy: 延迟创建 RealSubject" << std::endl;
realSubject = std::make_unique<RealSubject>();
}
realSubject->request();
}
};
int main() {
Proxy proxy1("guest");
proxy1.request();
Proxy proxy2("admin");
proxy2.request();
proxy2.request(); // 第二次不再创建
return 0;
}
优缺点:
| 优点 | 缺点 |
|---|---|
| 控制对真实对象的访问 | 增加请求处理延迟 |
| 可在不修改真实对象的情况下扩展 | 增加系统复杂度 |
| 支持延迟初始化,节省资源 | 代理与真实对象接口需保持一致 |
三、行为型模式(Behavioral Patterns)
行为型模式关注对象之间的通信,描述对象和类如何交互和分配职责。
13. 责任链模式(Chain of Responsibility)
意图:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
适用场景:
- 多级审批流程(请假、报销)
- 日志级别过滤
- 事件冒泡处理
UML 类图:
传递请求
<<abstract>>
Handler
-successor: Handler
+setSuccessor(Handler*) : void
+handleRequest(int) : void
ConcreteHandler1
+handleRequest(int) : void
ConcreteHandler2
+handleRequest(int) : void
ConcreteHandler3
+handleRequest(int) : void
C++ 实现:
cpp
#include <iostream>
#include <memory>
class Handler {
protected:
Handler* successor = nullptr;
public:
virtual ~Handler() = default;
void setSuccessor(Handler* s) { successor = s; }
virtual void handleRequest(int level) = 0;
};
class LowHandler : public Handler {
public:
void handleRequest(int level) override {
if (level <= 1) {
std::cout << "LowHandler 处理级别 " << level << " 的请求" << std::endl;
} else if (successor) {
successor->handleRequest(level);
}
}
};
class MidHandler : public Handler {
public:
void handleRequest(int level) override {
if (level <= 2) {
std::cout << "MidHandler 处理级别 " << level << " 的请求" << std::endl;
} else if (successor) {
successor->handleRequest(level);
}
}
};
class HighHandler : public Handler {
public:
void handleRequest(int level) override {
std::cout << "HighHandler 处理级别 " << level << " 的请求" << std::endl;
}
};
int main() {
LowHandler low;
MidHandler mid;
HighHandler high;
low.setSuccessor(&mid);
mid.setSuccessor(&high);
for (int i = 1; i <= 3; ++i)
low.handleRequest(i);
return 0;
}
优缺点:
| 优点 | 缺点 |
|---|---|
| 降低发送者和接收者的耦合 | 请求可能未被处理 |
| 动态组合处理链 | 链过长影响性能 |
| 符合单一职责原则 | 调试困难 |
14. 命令模式(Command)
意图:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。
适用场景:
- 撤销/重做功能
- 事务操作
- 任务队列、宏命令
UML 类图:
调用
持有
<<abstract>>
Command
+execute() : void
+undo() : void
ConcreteCommand
-receiver: Receiver
+execute() : void
+undo() : void
Receiver
+action() : void
+undoAction() : void
Invoker
-command: Command
+setCommand(Command*) : void
+executeCommand() : void
+undoCommand() : void
C++ 实现:
cpp
#include <iostream>
#include <memory>
#include <stack>
class Receiver {
public:
void action() { std::cout << "Receiver: 执行操作" << std::endl; }
void undoAction() { std::cout << "Receiver: 撤销操作" << std::endl; }
};
class Command {
public:
virtual ~Command() = default;
virtual void execute() = 0;
virtual void undo() = 0;
};
class ConcreteCommand : public Command {
Receiver* receiver;
public:
ConcreteCommand(Receiver* r) : receiver(r) {}
void execute() override { receiver->action(); }
void undo() override { receiver->undoAction(); }
};
class Invoker {
std::stack<std::unique_ptr<Command>> history;
public:
void executeCommand(std::unique_ptr<Command> cmd) {
cmd->execute();
history.push(std::move(cmd));
}
void undoLast() {
if (!history.empty()) {
history.top()->undo();
history.pop();
}
}
};
int main() {
Receiver receiver;
Invoker invoker;
invoker.executeCommand(std::make_unique<ConcreteCommand>(&receiver));
invoker.executeCommand(std::make_unique<ConcreteCommand>(&receiver));
invoker.undoLast();
return 0;
}
优缺点:
| 优点 | 缺点 |
|---|---|
| 解耦调用者和接收者 | 命令类数量增多 |
| 支持撤销/重做 | 简单操作也需封装 |
| 支持命令队列和日志 | 增加系统复杂度 |
15. 解释器模式(Interpreter)
意图:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
适用场景:
- SQL 解析、正则表达式
- 脚本语言解释器
- 数学表达式求值
UML 类图:
组合
组合
<<abstract>>
AbstractExpression
+interpret(context) : int
TerminalExpression
-value: int
+interpret(context) : int
AddExpression
-left: AbstractExpression
-right: AbstractExpression
+interpret(context) : int
SubExpression
-left: AbstractExpression
-right: AbstractExpression
+interpret(context) : int
C++ 实现(简单算术表达式):
cpp
#include <iostream>
#include <memory>
class Expression {
public:
virtual ~Expression() = default;
virtual int interpret() = 0;
};
class NumberExpr : public Expression {
int value;
public:
NumberExpr(int v) : value(v) {}
int interpret() override { return value; }
};
class AddExpr : public Expression {
std::unique_ptr<Expression> left, right;
public:
AddExpr(std::unique_ptr<Expression> l, std::unique_ptr<Expression> r)
: left(std::move(l)), right(std::move(r)) {}
int interpret() override { return left->interpret() + right->interpret(); }
};
class SubExpr : public Expression {
std::unique_ptr<Expression> left, right;
public:
SubExpr(std::unique_ptr<Expression> l, std::unique_ptr<Expression> r)
: left(std::move(l)), right(std::move(r)) {}
int interpret() override { return left->interpret() - right->interpret(); }
};
int main() {
// 表达式: (5 + 3) - 2
auto expr = std::make_unique<SubExpr>(
std::make_unique<AddExpr>(
std::make_unique<NumberExpr>(5),
std::make_unique<NumberExpr>(3)
),
std::make_unique<NumberExpr>(2)
);
std::cout << "结果: " << expr->interpret() << std::endl; // 6
return 0;
}
优缺点:
| 优点 | 缺点 |
|---|---|
| 易于扩展文法 | 复杂文法难以维护 |
| 每条规则对应一个类,清晰 | 类数量随文法规则增多 |
| 可组合表达式 | 执行效率较低 |
16. 迭代器模式(Iterator)
意图:提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示。
适用场景:
- 遍历集合而不暴露内部结构
- 支持多种遍历方式
- 统一不同集合的遍历接口
UML 类图:
遍历
创建
<<abstract>>
Iterator
+hasNext() : bool
+next() : int
ConcreteIterator
-collection: ConcreteCollection
-index: int
+hasNext() : bool
+next() : int
<<abstract>>
Aggregate
+createIterator() : Iterator
ConcreteCollection
-items: vector<int>
+createIterator() : Iterator
+getItem(int) : int
+size() : int
C++ 实现:
cpp
#include <iostream>
#include <vector>
#include <memory>
class Iterator {
public:
virtual ~Iterator() = default;
virtual bool hasNext() = 0;
virtual int next() = 0;
};
class ConcreteCollection;
class ConcreteIterator : public Iterator {
const ConcreteCollection* collection;
size_t index = 0;
public:
ConcreteIterator(const ConcreteCollection* c) : collection(c) {}
bool hasNext() override;
int next() override;
};
class ConcreteCollection {
std::vector<int> items;
public:
void add(int item) { items.push_back(item); }
size_t size() const { return items.size(); }
int getItem(size_t i) const { return items[i]; }
std::unique_ptr<Iterator> createIterator() const {
return std::make_unique<ConcreteIterator>(this);
}
};
bool ConcreteIterator::hasNext() { return index < collection->size(); }
int ConcreteIterator::next() { return collection->getItem(index++); }
int main() {
ConcreteCollection col;
for (int i = 1; i <= 5; ++i) col.add(i * 10);
auto it = col.createIterator();
while (it->hasNext())
std::cout << it->next() << " ";
std::cout << std::endl;
return 0;
}
优缺点:
| 优点 | 缺点 |
|---|---|
| 统一遍历接口 | 简单集合增加复杂度 |
| 支持多种遍历方式 | 迭代器与集合耦合 |
| 符合单一职责原则 | C++ STL 已内置,较少手写 |
17. 中介者模式(Mediator)
意图:用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
适用场景:
- 聊天室(用户通过服务器通信)
- 航空管制(飞机通过塔台通信)
- GUI 组件间通信
UML 类图:
通知
<<abstract>>
Mediator
+notify(sender, event) : void
ConcreteMediator
-component1: Component1
-component2: Component2
+notify(sender, event) : void
Component
#mediator: Mediator
+setMediator(Mediator*) : void
Component1
+doA() : void
+doB() : void
Component2
+doC() : void
+doD() : void
C++ 实现:
cpp
#include <iostream>
#include <string>
class Mediator;
class Component {
protected:
Mediator* mediator = nullptr;
public:
virtual ~Component() = default;
void setMediator(Mediator* m) { mediator = m; }
virtual std::string name() = 0;
};
class Mediator {
public:
virtual ~Mediator() = default;
virtual void notify(Component* sender, const std::string& event) = 0;
};
class ComponentA : public Component {
public:
std::string name() override { return "ComponentA"; }
void doA();
void doB();
};
class ComponentB : public Component {
public:
std::string name() override { return "ComponentB"; }
void doC();
void doD();
};
class ConcreteMediator : public Mediator {
ComponentA* a;
ComponentB* b;
public:
ConcreteMediator(ComponentA* ca, ComponentB* cb) : a(ca), b(cb) {
a->setMediator(this);
b->setMediator(this);
}
void notify(Component* sender, const std::string& event) override {
std::cout << "中介者收到 [" << sender->name() << "] 事件: " << event << std::endl;
if (event == "A") b->doC();
else if (event == "D") a->doB();
}
};
void ComponentA::doA() { std::cout << "ComponentA::doA()" << std::endl; mediator->notify(this, "A"); }
void ComponentA::doB() { std::cout << "ComponentA::doB()" << std::endl; }
void ComponentB::doC() { std::cout << "ComponentB::doC()" << std::endl; }
void ComponentB::doD() { std::cout << "ComponentB::doD()" << std::endl; mediator->notify(this, "D"); }
int main() {
ComponentA a;
ComponentB b;
ConcreteMediator mediator(&a, &b);
a.doA();
std::cout << "---" << std::endl;
b.doD();
return 0;
}
优缺点:
| 优点 | 缺点 |
|---|---|
| 减少组件间的直接依赖 | 中介者可能变成"上帝对象" |
| 集中控制交互逻辑 | 中介者本身复杂度高 |
| 组件可复用 | 难以维护大型中介者 |
18. 备忘录模式(Memento)
意图:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。
适用场景:
- 编辑器撤销/重做
- 游戏存档
- 事务回滚
UML 类图:
创建/恢复
保存
Originator
-state: string
+setState(string) : void
+getState() : string
+createMemento() : Memento
+restoreMemento(Memento) : void
Memento
-state: string
+getState() : string
Caretaker
-mementos: stack<Memento>
+save(Memento) : void
+undo() : Memento
C++ 实现:
cpp
#include <iostream>
#include <string>
#include <stack>
class Memento {
std::string state;
public:
Memento(const std::string& s) : state(s) {}
std::string getState() const { return state; }
};
class Originator {
std::string state;
public:
void setState(const std::string& s) {
state = s;
std::cout << "状态设置为: " << state << std::endl;
}
std::string getState() const { return state; }
Memento createMemento() const { return Memento(state); }
void restoreMemento(const Memento& m) {
state = m.getState();
std::cout << "状态恢复为: " << state << std::endl;
}
};
class Caretaker {
std::stack<Memento> history;
public:
void save(const Memento& m) { history.push(m); }
Memento undo() {
Memento m = history.top();
history.pop();
return m;
}
bool hasHistory() const { return !history.empty(); }
};
int main() {
Originator originator;
Caretaker caretaker;
originator.setState("状态1");
caretaker.save(originator.createMemento());
originator.setState("状态2");
caretaker.save(originator.createMemento());
originator.setState("状态3");
originator.restoreMemento(caretaker.undo());
originator.restoreMemento(caretaker.undo());
return 0;
}
优缺点:
| 优点 | 缺点 |
|---|---|
| 不破坏封装性保存状态 | 频繁保存消耗内存 |
| 简化发起人职责 | 管理者需了解生命周期 |
| 支持撤销操作 | 深拷贝复杂对象代价高 |
19. 观察者模式(Observer)
意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
适用场景:
- 事件系统、消息总线
- MVC 中 Model 通知 View
- 股票价格订阅
UML 类图:
通知
观察
观察
<<abstract>>
Subject
-observers: list<Observer*>
+attach(Observer*) : void
+detach(Observer*) : void
+notify() : void
ConcreteSubject
-state: int
+getState() : int
+setState(int) : void
<<abstract>>
Observer
+update() : void
ConcreteObserverA
+update() : void
ConcreteObserverB
+update() : void
C++ 实现:
cpp
#include <iostream>
#include <list>
#include <algorithm>
class Observer {
public:
virtual ~Observer() = default;
virtual void update(int state) = 0;
};
class Subject {
std::list<Observer*> observers;
int state = 0;
public:
void attach(Observer* o) { observers.push_back(o); }
void detach(Observer* o) { observers.remove(o); }
void setState(int s) {
state = s;
notify();
}
int getState() const { return state; }
private:
void notify() {
for (auto* o : observers) o->update(state);
}
};
class ObserverA : public Observer {
public:
void update(int state) override {
std::cout << "ObserverA 收到状态: " << state << std::endl;
}
};
class ObserverB : public Observer {
public:
void update(int state) override {
std::cout << "ObserverB 收到状态: " << state << std::endl;
}
};
int main() {
Subject subject;
ObserverA a;
ObserverB b;
subject.attach(&a);
subject.attach(&b);
subject.setState(42);
subject.detach(&a);
subject.setState(100);
return 0;
}
优缺点:
| 优点 | 缺点 |
|---|---|
| 松耦合,主题不知道观察者细节 | 通知顺序不确定 |
| 支持广播通信 | 观察者过多影响性能 |
| 符合开闭原则 | 可能引发循环依赖 |
20. 状态模式(State)
意图:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
适用场景:
- 订单状态机(待支付→已支付→已发货→已完成)
- 游戏角色状态(正常/受伤/死亡)
- TCP 连接状态
UML 类图:
持有
Context
-state: State
+setState(State*) : void
+request() : void
<<abstract>>
State
+handle(Context*) : void
StateA
+handle(Context*) : void
StateB
+handle(Context*) : void
C++ 实现:
cpp
#include <iostream>
#include <memory>
class Context;
class State {
public:
virtual ~State() = default;
virtual void handle(Context* ctx) = 0;
virtual std::string name() = 0;
};
class Context {
std::unique_ptr<State> state;
public:
void setState(std::unique_ptr<State> s) {
std::cout << "状态切换到: " << s->name() << std::endl;
state = std::move(s);
}
void request() { state->handle(this); }
};
class StateA : public State {
public:
std::string name() override { return "StateA"; }
void handle(Context* ctx) override;
};
class StateB : public State {
public:
std::string name() override { return "StateB"; }
void handle(Context* ctx) override;
};
void StateA::handle(Context* ctx) {
std::cout << "StateA 处理请求,切换到 StateB" << std::endl;
ctx->setState(std::make_unique<StateB>());
}
void StateB::handle(Context* ctx) {
std::cout << "StateB 处理请求,切换到 StateA" << std::endl;
ctx->setState(std::make_unique<StateA>());
}
int main() {
Context ctx;
ctx.setState(std::make_unique<StateA>());
ctx.request();
ctx.request();
ctx.request();
return 0;
}
优缺点:
| 优点 | 缺点 |
|---|---|
| 消除大量条件分支 | 状态类数量增多 |
| 状态转换逻辑集中 | 状态切换逻辑分散在各状态类 |
| 符合开闭原则 | 简单状态机反而复杂 |
21. 策略模式(Strategy)
意图:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
适用场景:
- 排序算法切换
- 支付方式选择(微信/支付宝/银行卡)
- 压缩算法选择
UML 类图:
持有
Context
-strategy: Strategy
+setStrategy(Strategy*) : void
+executeStrategy() : void
<<abstract>>
Strategy
+execute() : void
ConcreteStrategyA
+execute() : void
ConcreteStrategyB
+execute() : void
ConcreteStrategyC
+execute() : void
C++ 实现:
cpp
#include <iostream>
#include <memory>
#include <vector>
#include <algorithm>
class SortStrategy {
public:
virtual ~SortStrategy() = default;
virtual void sort(std::vector<int>& data) = 0;
virtual std::string name() = 0;
};
class BubbleSort : public SortStrategy {
public:
std::string name() override { return "冒泡排序"; }
void sort(std::vector<int>& data) override {
for (size_t i = 0; i < data.size(); ++i)
for (size_t j = 0; j + 1 < data.size() - i; ++j)
if (data[j] > data[j+1]) std::swap(data[j], data[j+1]);
}
};
class StdSort : public SortStrategy {
public:
std::string name() override { return "标准库排序"; }
void sort(std::vector<int>& data) override {
std::sort(data.begin(), data.end());
}
};
class Sorter {
std::unique_ptr<SortStrategy> strategy;
public:
void setStrategy(std::unique_ptr<SortStrategy> s) { strategy = std::move(s); }
void sort(std::vector<int>& data) {
std::cout << "使用 " << strategy->name() << std::endl;
strategy->sort(data);
}
};
int main() {
std::vector<int> data = {5, 2, 8, 1, 9, 3};
Sorter sorter;
sorter.setStrategy(std::make_unique<BubbleSort>());
sorter.sort(data);
data = {5, 2, 8, 1, 9, 3};
sorter.setStrategy(std::make_unique<StdSort>());
sorter.sort(data);
return 0;
}
优缺点:
| 优点 | 缺点 |
|---|---|
| 算法可自由切换 | 客户端需了解所有策略 |
| 消除条件分支 | 策略类数量增多 |
| 符合开闭原则 | 简单场景反而复杂 |
22. 模板方法模式(Template Method)
意图:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
适用场景:
- 数据处理流程(读取→处理→输出)
- 游戏初始化流程
- 单元测试框架(setUp→test→tearDown)
UML 类图:
AbstractClass
+templateMethod() : void
#step1() : void
#step2() : void
#hook() : void
ConcreteClassA
#step1() : void
#step2() : void
ConcreteClassB
#step1() : void
#step2() : void
#hook() : void
C++ 实现:
cpp
#include <iostream>
class DataProcessor {
public:
void process() {
readData();
processData();
if (needOutput()) writeOutput();
}
protected:
virtual void readData() = 0;
virtual void processData() = 0;
virtual void writeOutput() {
std::cout << "默认输出结果" << std::endl;
}
virtual bool needOutput() { return true; } // 钩子方法
};
class CSVProcessor : public DataProcessor {
protected:
void readData() override { std::cout << "读取 CSV 文件" << std::endl; }
void processData() override { std::cout << "解析 CSV 数据" << std::endl; }
void writeOutput() override { std::cout << "输出 CSV 结果" << std::endl; }
};
class JSONProcessor : public DataProcessor {
protected:
void readData() override { std::cout << "读取 JSON 文件" << std::endl; }
void processData() override { std::cout << "解析 JSON 数据" << std::endl; }
bool needOutput() override { return false; } // 不需要输出
};
int main() {
CSVProcessor csv;
csv.process();
std::cout << "---" << std::endl;
JSONProcessor json;
json.process();
return 0;
}
优缺点:
| 优点 | 缺点 |
|---|---|
| 复用算法骨架 | 子类数量增多 |
| 钩子方法提供扩展点 | 违反里氏替换原则风险 |
| 控制子类扩展点 | 算法骨架修改影响所有子类 |
23. 访问者模式(Visitor)
意图:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
适用场景:
- 编译器 AST 遍历(类型检查、代码生成)
- 文档导出(同一文档导出为 PDF/HTML/Word)
- 对象结构稳定但操作频繁变化
UML 类图:
accept
accept
<<abstract>>
Visitor
+visitConcreteElementA(ConcreteElementA*) : void
+visitConcreteElementB(ConcreteElementB*) : void
ConcreteVisitor1
+visitConcreteElementA(ConcreteElementA*) : void
+visitConcreteElementB(ConcreteElementB*) : void
ConcreteVisitor2
+visitConcreteElementA(ConcreteElementA*) : void
+visitConcreteElementB(ConcreteElementB*) : void
<<abstract>>
Element
+accept(Visitor*) : void
ConcreteElementA
+accept(Visitor*) : void
+operationA() : void
ConcreteElementB
+accept(Visitor*) : void
+operationB() : void
C++ 实现:
cpp
#include <iostream>
#include <vector>
#include <memory>
class ConcreteElementA;
class ConcreteElementB;
class Visitor {
public:
virtual ~Visitor() = default;
virtual void visit(ConcreteElementA* e) = 0;
virtual void visit(ConcreteElementB* e) = 0;
};
class Element {
public:
virtual ~Element() = default;
virtual void accept(Visitor* v) = 0;
};
class ConcreteElementA : public Element {
public:
void accept(Visitor* v) override { v->visit(this); }
std::string operationA() { return "ElementA"; }
};
class ConcreteElementB : public Element {
public:
void accept(Visitor* v) override { v->visit(this); }
std::string operationB() { return "ElementB"; }
};
class PrintVisitor : public Visitor {
public:
void visit(ConcreteElementA* e) override {
std::cout << "PrintVisitor 访问 " << e->operationA() << std::endl;
}
void visit(ConcreteElementB* e) override {
std::cout << "PrintVisitor 访问 " << e->operationB() << std::endl;
}
};
class CountVisitor : public Visitor {
int count = 0;
public:
void visit(ConcreteElementA*) override { ++count; }
void visit(ConcreteElementB*) override { ++count; }
int getCount() const { return count; }
};
int main() {
std::vector<std::unique_ptr<Element>> elements;
elements.push_back(std::make_unique<ConcreteElementA>());
elements.push_back(std::make_unique<ConcreteElementB>());
elements.push_back(std::make_unique<ConcreteElementA>());
PrintVisitor printer;
CountVisitor counter;
for (auto& e : elements) {
e->accept(&printer);
e->accept(&counter);
}
std::cout << "元素总数: " << counter.getCount() << std::endl;
return 0;
}
优缺点:
| 优点 | 缺点 |
|---|---|
| 新增操作无需修改元素类 | 新增元素类需修改所有访问者 |
| 相关操作集中在访问者中 | 破坏元素类的封装性 |
| 可积累状态(如 CountVisitor) | 元素类层次结构需稳定 |
总结
| 类型 | 模式 | 核心意图 |
|---|---|---|
| 创建型 | 单例 | 唯一实例 |
| 工厂方法 | 子类决定实例化 | |
| 抽象工厂 | 产品族创建 | |
| 建造者 | 分步构建复杂对象 | |
| 原型 | 克隆创建对象 | |
| 结构型 | 适配器 | 接口转换 |
| 桥接 | 抽象与实现分离 | |
| 组合 | 树形结构统一处理 | |
| 装饰 | 动态添加职责 | |
| 外观 | 简化子系统接口 | |
| 享元 | 共享减少内存 | |
| 代理 | 控制对象访问 | |
| 行为型 | 责任链 | 请求沿链传递 |
| 命令 | 请求封装为对象 | |
| 解释器 | 语言文法解释 | |
| 迭代器 | 统一遍历接口 | |
| 中介者 | 集中对象交互 | |
| 备忘录 | 保存/恢复状态 | |
| 观察者 | 一对多通知 | |
| 状态 | 状态驱动行为 | |
| 策略 | 算法可替换 | |
| 模板方法 | 算法骨架固定 | |
| 访问者 | 不改类添加操作 |