下面介绍经典的23种设计模式,并分别用C++示例代码加以说明。本文分为三大类:创建型模式、结构型模式和行为型模式,每种模式简要说明其意图、关键思想和优缺点,并给出一个精简的C++代码示例。
一、创建型模式
创建型模式关注对象的创建问题,封装对象实例化过程,使客户端与具体产品解耦。
1. 抽象工厂模式 (Abstract Factory)
意图:提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定具体类。
特点:将产品族的创建封装到同一个工厂中,便于更换产品族。
C++示例:
#include <iostream>
#include <memory>
using namespace std;
// 抽象产品A
class AbstractProductA {
public:
virtual void info() = 0;
virtual ~AbstractProductA() {}
};
// 抽象产品B
class AbstractProductB {
public:
virtual void info() = 0;
virtual ~AbstractProductB() {}
};
// 具体产品A1
class ConcreteProductA1 : public AbstractProductA {
public:
void info() override { cout << "ConcreteProductA1" << endl; }
};
// 具体产品B1
class ConcreteProductB1 : public AbstractProductB {
public:
void info() override { cout << "ConcreteProductB1" << endl; }
};
// 抽象工厂
class AbstractFactory {
public:
virtual unique_ptr<AbstractProductA> createProductA() = 0;
virtual unique_ptr<AbstractProductB> createProductB() = 0;
virtual ~AbstractFactory() {}
};
// 具体工厂1
class ConcreteFactory1 : public AbstractFactory {
public:
unique_ptr<AbstractProductA> createProductA() override {
return make_unique<ConcreteProductA1>();
}
unique_ptr<AbstractProductB> createProductB() override {
return make_unique<ConcreteProductB1>();
}
};
int main(){
unique_ptr<AbstractFactory> factory = make_unique<ConcreteFactory1>();
auto productA = factory->createProductA();
auto productB = factory->createProductB();
productA->info();
productB->info();
return 0;
}
2. 建造者模式 (Builder)
意图:将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。
特点:分步骤构造产品,使用 Director 控制组装顺序。
C++示例:
#include <iostream>
#include <string>
#include <memory>
using namespace std;
// 产品
class Product {
public:
string partA, partB, partC;
void show() {
cout << "Product parts: " << partA << ", " << partB << ", " << partC << endl;
}
};
// 抽象建造者
class Builder {
public:
virtual void buildPartA() = 0;
virtual void buildPartB() = 0;
virtual void buildPartC() = 0;
virtual unique_ptr<Product> getResult() = 0;
virtual ~Builder() {}
};
// 具体建造者
class ConcreteBuilder : public Builder {
private:
unique_ptr<Product> product;
public:
ConcreteBuilder() { product = make_unique<Product>(); }
void buildPartA() override { product->partA = "A"; }
void buildPartB() override { product->partB = "B"; }
void buildPartC() override { product->partC = "C"; }
unique_ptr<Product> getResult() override { return move(product); }
};
// 导演
class Director {
private:
Builder* builder;
public:
Director(Builder* b) : builder(b) {}
void construct() {
builder->buildPartA();
builder->buildPartB();
builder->buildPartC();
}
};
int main(){
ConcreteBuilder builder;
Director director(&builder);
director.construct();
auto product = builder.getResult();
product->show();
return 0;
}
3. 工厂方法模式 (Factory Method)
意图:定义一个创建对象的接口,让子类决定实例化哪一个类,从而将实例化推迟到子类。
特点:每个子类工厂负责生产一种产品,便于扩展。
C++示例:
#include <iostream>
#include <memory>
using namespace std;
// 抽象产品
class Product {
public:
virtual void operation() = 0;
virtual ~Product() {}
};
// 具体产品
class ConcreteProduct : public Product {
public:
void operation() override { cout << "ConcreteProduct operation" << endl; }
};
// 抽象工厂
class Creator {
public:
virtual unique_ptr<Product> factoryMethod() = 0;
virtual ~Creator() {}
};
// 具体工厂
class ConcreteCreator : public Creator {
public:
unique_ptr<Product> factoryMethod() override {
return make_unique<ConcreteProduct>();
}
};
int main(){
unique_ptr<Creator> creator = make_unique<ConcreteCreator>();
auto product = creator->factoryMethod();
product->operation();
return 0;
}
4. 原型模式 (Prototype)
意图:通过复制现有实例来创建新的实例,而无需了解其具体类。
特点:利用克隆方法(通常实现虚拟的clone()函数)复制对象。
C++示例:
#include <iostream>
#include <memory>
using namespace std;
// 抽象原型
class Prototype {
public:
virtual unique_ptr<Prototype> clone() = 0;
virtual void info() = 0;
virtual ~Prototype() {}
};
// 具体原型
class ConcretePrototype : public Prototype {
int data;
public:
ConcretePrototype(int d) : data(d) {}
unique_ptr<Prototype> clone() override {
return make_unique<ConcretePrototype>(*this);
}
void info() override {
cout << "ConcretePrototype with data " << data << endl;
}
};
int main(){
unique_ptr<Prototype> prototype = make_unique<ConcretePrototype>(42);
auto clone = prototype->clone();
clone->info();
return 0;
}
5. 单例模式 (Singleton)
意图:保证一个类只有一个实例,并提供全局访问点。
特点:构造函数私有,通过静态方法返回唯一实例。
C++示例:
#include <iostream>
#include <mutex>
using namespace std;
class Singleton {
private:
static Singleton* instance;
static mutex mtx;
// 私有构造函数
Singleton() { cout << "Singleton created." << endl; }
public:
// 禁止复制
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
static Singleton* getInstance() {
if(!instance) {
lock_guard<mutex> lock(mtx);
if(!instance)
instance = new Singleton();
}
return instance;
}
void operation() { cout << "Singleton operation." << endl; }
};
Singleton* Singleton::instance = nullptr;
mutex Singleton::mtx;
int main(){
Singleton::getInstance()->operation();
return 0;
}
二、结构型模式
结构型模式主要关注如何将类或对象组合成更大的结构,以达到更好的组织和复用。
6. 适配器模式 (Adapter)
意图:将一个类的接口转换为客户期望的另一个接口,从而使原本不兼容的类可以协同工作。
C++示例:
#include <iostream>
using namespace std;
// 目标接口
class Target {
public:
virtual void request() = 0;
virtual ~Target() {}
};
// 现有类(需要适配)
class Adaptee {
public:
void specificRequest() {
cout << "Adaptee specificRequest" << endl;
}
};
// 适配器
class Adapter : public Target {
private:
Adaptee adaptee;
public:
void request() override {
adaptee.specificRequest();
}
};
int main(){
Target* t = new Adapter();
t->request();
delete t;
return 0;
}
7. 桥接模式 (Bridge)
意图:将抽象部分与实现部分分离,使它们可以独立变化。
特点:通过组合而非继承连接抽象与实现。
C++示例:
#include <iostream>
using namespace std;
// 实现接口
class Implementor {
public:
virtual void operationImpl() = 0;
virtual ~Implementor() {}
};
class ConcreteImplementorA : public Implementor {
public:
void operationImpl() override { cout << "ConcreteImplementorA" << endl; }
};
// 抽象部分
class Abstraction {
protected:
Implementor* imp;
public:
Abstraction(Implementor* i) : imp(i) {}
virtual void operation() { imp->operationImpl(); }
virtual ~Abstraction() { delete imp; }
};
int main(){
Abstraction* abs = new Abstraction(new ConcreteImplementorA());
abs->operation();
delete abs;
return 0;
}
8. 组合模式 (Composite)
意图:将对象组合成树形结构,以表示“部分-整体”的层次结构,使客户端对单个对象和组合对象一视同仁。
C++示例:
#include <iostream>
#include <vector>
using namespace std;
// 抽象组件
class Component {
public:
virtual void operation() = 0;
virtual void add(Component* c) {}
virtual ~Component() {}
};
// 叶子
class Leaf : public Component {
public:
void operation() override { cout << "Leaf operation" << endl; }
};
// 组合对象
class Composite : public Component {
vector<Component*> children;
public:
void add(Component* c) override { children.push_back(c); }
void operation() override {
cout << "Composite operation:" << endl;
for(auto c : children) {
c->operation();
}
}
~Composite(){
for(auto c : children) delete c;
}
};
int main(){
Composite comp;
comp.add(new Leaf());
comp.add(new Leaf());
comp.operation();
return 0;
}
9. 装饰器模式 (Decorator)
意图:动态地给一个对象添加额外的职责或功能,而不改变其接口。
特点:通过包装对象实现功能的增强。
C++示例:
#include <iostream>
using namespace std;
// 组件接口
class Component {
public:
virtual void operation() = 0;
virtual ~Component() {}
};
// 具体组件
class ConcreteComponent : public Component {
public:
void operation() override { cout << "ConcreteComponent" << endl; }
};
// 装饰器基类
class Decorator : public Component {
protected:
Component* component;
public:
Decorator(Component* comp) : component(comp) {}
virtual ~Decorator() { delete component; }
};
// 具体装饰器
class ConcreteDecorator : public Decorator {
public:
ConcreteDecorator(Component* comp) : Decorator(comp) {}
void operation() override {
cout << "ConcreteDecorator before ";
component->operation();
cout << "ConcreteDecorator after" << endl;
}
};
int main(){
Component* comp = new ConcreteDecorator(new ConcreteComponent());
comp->operation();
delete comp;
return 0;
}
10. 外观模式 (Facade)
意图:为子系统中的一组接口提供一个统一的高层接口,从而简化子系统的使用。
C++示例:
#include <iostream>
using namespace std;
// 子系统A
class SubsystemA {
public:
void operationA() { cout << "SubsystemA operation" << endl; }
};
// 子系统B
class SubsystemB {
public:
void operationB() { cout << "SubsystemB operation" << endl; }
};
// 外观
class Facade {
SubsystemA a;
SubsystemB b;
public:
void operation() {
a.operationA();
b.operationB();
}
};
int main(){
Facade facade;
facade.operation();
return 0;
}
11. 享元模式 (Flyweight)
意图:通过共享技术有效地支持大量细粒度对象的复用,减少内存占用。
C++示例:
#include <iostream>
#include <unordered_map>
#include <string>
using namespace std;
class Flyweight {
string intrinsicState;
public:
Flyweight(const string& state) : intrinsicState(state) {}
void operation(const string& extrinsicState) {
cout << "Intrinsic: " << intrinsicState << ", Extrinsic: " << extrinsicState << endl;
}
};
class FlyweightFactory {
unordered_map<string, Flyweight*> pool;
public:
~FlyweightFactory(){
for(auto p : pool) delete p.second;
}
Flyweight* getFlyweight(const string& key) {
if(pool.find(key) == pool.end()){
pool[key] = new Flyweight(key);
}
return pool[key];
}
};
int main(){
FlyweightFactory factory;
Flyweight* fw1 = factory.getFlyweight("shared");
fw1->operation("one");
Flyweight* fw2 = factory.getFlyweight("shared");
fw2->operation("two");
return 0;
}
12. 代理模式 (Proxy)
意图:为其他对象提供一个代理以控制对这个对象的访问。
特点:可以在不修改原对象代码的情况下增加访问控制、延迟加载等功能。
C++示例:
#include <iostream>
using namespace std;
// 抽象主题
class Subject {
public:
virtual void request() = 0;
virtual ~Subject() {}
};
// 真实主题
class RealSubject : public Subject {
public:
void request() override { cout << "RealSubject request" << endl; }
};
// 代理
class Proxy : public Subject {
RealSubject* real;
public:
Proxy() : real(new RealSubject()) {}
~Proxy(){ delete real; }
void request() override {
cout << "Proxy checking access..." << endl;
real->request();
}
};
int main(){
Subject* s = new Proxy();
s->request();
delete s;
return 0;
}
三、行为型模式
行为型模式关注对象之间的通信与职责分配,描述了对象如何协作完成任务。
13. 责任链模式 (Chain of Responsibility)
意图:使多个对象都有机会处理请求,将这些对象连成一条链,并沿着链传递请求,直到有对象处理。
C++示例:
#include <iostream>
using namespace std;
class Handler {
protected:
Handler* next;
public:
Handler() : next(nullptr) {}
void setNext(Handler* h) { next = h; }
virtual void handleRequest(int request) {
if(next)
next->handleRequest(request);
}
virtual ~Handler() {}
};
class ConcreteHandler1 : public Handler {
public:
void handleRequest(int request) override {
if(request < 10)
cout << "ConcreteHandler1 handled " << request << endl;
else if(next)
next->handleRequest(request);
}
};
class ConcreteHandler2 : public Handler {
public:
void handleRequest(int request) override {
if(request >= 10)
cout << "ConcreteHandler2 handled " << request << endl;
else if(next)
next->handleRequest(request);
}
};
int main(){
ConcreteHandler1 h1;
ConcreteHandler2 h2;
h1.setNext(&h2);
h1.handleRequest(5);
h1.handleRequest(15);
return 0;
}
14. 命令模式 (Command)
意图:将请求封装成对象,从而使你可以用不同的请求对客户进行参数化、排队或记录请求。
特点:将请求的调用者与执行者解耦。
C++示例:
#include <iostream>
#include <vector>
using namespace std;
// 命令接口
class Command {
public:
virtual void execute() = 0;
virtual ~Command() {}
};
// 具体命令
class ConcreteCommand : public Command {
int data;
public:
ConcreteCommand(int d) : data(d) {}
void execute() override { cout << "Executing command with data " << data << endl; }
};
// 调用者
class Invoker {
vector<Command*> commands;
public:
void addCommand(Command* cmd) { commands.push_back(cmd); }
void run() {
for(auto cmd : commands) {
cmd->execute();
}
}
~Invoker(){
for(auto cmd : commands) delete cmd;
}
};
int main(){
Invoker invoker;
invoker.addCommand(new ConcreteCommand(100));
invoker.addCommand(new ConcreteCommand(200));
invoker.run();
return 0;
}
15. 解释器模式 (Interpreter)
意图:给定一个语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。
特点:适用于简单语言或表达式求值。
C++示例(求和表达式):
#include <iostream>
#include <sstream>
using namespace std;
// 抽象表达式
class Expression {
public:
virtual int interpret() = 0;
virtual ~Expression() {}
};
// 数字表达式
class Number : public Expression {
int value;
public:
Number(int v) : value(v) {}
int interpret() override { return value; }
};
// 加法表达式
class Add : public Expression {
Expression *left, *right;
public:
Add(Expression* l, Expression* r) : left(l), right(r) {}
int interpret() override { return left->interpret() + right->interpret(); }
~Add(){ delete left; delete right; }
};
int main(){
// 表达式:3 + 4
Expression* expr = new Add(new Number(3), new Number(4));
cout << "Result: " << expr->interpret() << endl;
delete expr;
return 0;
}
16. 迭代器模式 (Iterator)
意图:提供一种方法顺序访问聚合对象中的各个元素,而不暴露该对象的内部表示。
C++示例(简单数组迭代器):
#include <iostream>
#include <vector>
using namespace std;
template<typename T>
class Iterator {
const vector<T>& collection;
size_t index;
public:
Iterator(const vector<T>& coll) : collection(coll), index(0) {}
bool hasNext() { return index < collection.size(); }
T next() { return collection[index++]; }
};
int main(){
vector<int> nums = {1,2,3,4,5};
Iterator<int> it(nums);
while(it.hasNext()){
cout << it.next() << " ";
}
cout << endl;
return 0;
}
17. 中介者模式 (Mediator)
意图:用一个中介对象封装一系列对象交互,使各对象不需要显式相互引用,从而降低耦合。
C++示例:
#include <iostream>
#include <string>
using namespace std;
class Colleague; // 前置声明
// 中介者接口
class Mediator {
public:
virtual void send(const string& message, Colleague* colleague) = 0;
virtual ~Mediator() {}
};
// 同事抽象类
class Colleague {
protected:
Mediator* mediator;
public:
Colleague(Mediator* m) : mediator(m) {}
virtual void receive(const string& message) = 0;
void send(const string& message) { mediator->send(message, this); }
virtual ~Colleague() {}
};
class ConcreteColleague1 : public Colleague {
public:
ConcreteColleague1(Mediator* m) : Colleague(m) {}
void receive(const string& message) override { cout << "Colleague1 received: " << message << endl; }
};
class ConcreteColleague2 : public Colleague {
public:
ConcreteColleague2(Mediator* m) : Colleague(m) {}
void receive(const string& message) override { cout << "Colleague2 received: " << message << endl; }
};
class ConcreteMediator : public Mediator {
Colleague* colleague1;
Colleague* colleague2;
public:
void setColleagues(Colleague* c1, Colleague* c2) {
colleague1 = c1; colleague2 = c2;
}
void send(const string& message, Colleague* colleague) override {
if(colleague == colleague1)
colleague2->receive(message);
else
colleague1->receive(message);
}
};
int main(){
ConcreteMediator mediator;
ConcreteColleague1 c1(&mediator);
ConcreteColleague2 c2(&mediator);
mediator.setColleagues(&c1, &c2);
c1.send("Hello from c1");
c2.send("Hi from c2");
return 0;
}
18. 备忘录模式 (Memento)
意图:在不破坏封装的前提下,捕获一个对象的内部状态,并在以后将该对象恢复到先前状态。
C++示例:
#include <iostream>
#include <string>
using namespace std;
// 备忘录
class Memento {
string state;
public:
Memento(const string& s) : state(s) {}
string getState() const { return state; }
};
// 发起人
class Originator {
string state;
public:
void setState(const string& s) { state = s; }
string getState() const { return state; }
Memento* saveStateToMemento() { return new Memento(state); }
void getStateFromMemento(Memento* m) { state = m->getState(); }
};
int main(){
Originator originator;
originator.setState("State1");
Memento* m = originator.saveStateToMemento();
originator.setState("State2");
cout << "Current State: " << originator.getState() << endl;
originator.getStateFromMemento(m);
cout << "Restored State: " << originator.getState() << endl;
delete m;
return 0;
}
19. 观察者模式 (Observer)
意图:定义一种一对多的依赖关系,当一个对象状态发生改变时,所有依赖它的对象都会收到通知。
C++示例:
#include <iostream>
#include <vector>
using namespace std;
class Observer {
public:
virtual void update(int state) = 0;
virtual ~Observer() {}
};
class Subject {
vector<Observer*> observers;
int state;
public:
void attach(Observer* o) { observers.push_back(o); }
void setState(int s) {
state = s;
notifyAllObservers();
}
void notifyAllObservers() {
for(auto o : observers)
o->update(state);
}
};
class ConcreteObserver : public Observer {
string name;
public:
ConcreteObserver(const string& n) : name(n) {}
void update(int state) override {
cout << "Observer " << name << " updated to state " << state << endl;
}
};
int main(){
Subject subject;
ConcreteObserver o1("A"), o2("B");
subject.attach(&o1);
subject.attach(&o2);
subject.setState(10);
return 0;
}
20. 状态模式 (State)
意图:允许一个对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。
C++示例:
#include <iostream>
using namespace std;
class Context; // 前置声明
// 状态接口
class State {
public:
virtual void handle(Context* context) = 0;
virtual ~State() {}
};
class Context {
State* state;
public:
Context(State* s) : state(s) {}
void setState(State* s) { state = s; }
void request() { state->handle(this); }
};
class ConcreteStateA : public State {
public:
void handle(Context* context) override {
cout << "State A handling request and switching to State B" << endl;
// 这里切换状态(示例不完全管理内存)
context->setState(new ConcreteStateB());
delete this;
}
};
class ConcreteStateB : public State {
public:
void handle(Context* context) override {
cout << "State B handling request and switching to State A" << endl;
context->setState(new ConcreteStateA());
delete this;
}
};
int main(){
// 初始状态为A
Context* context = new Context(new ConcreteStateA());
context->request(); // A处理,切换到B
context->request(); // B处理,切换到A
delete context;
return 0;
}
21. 策略模式 (Strategy)
意图:定义一系列算法,将每个算法封装起来,使它们可以互换,策略模式使得算法独立于使用它的客户而变化。
C++示例:
#include <iostream>
using namespace std;
// 策略接口
class Strategy {
public:
virtual int doOperation(int a, int b) = 0;
virtual ~Strategy() {}
};
class OperationAdd : public Strategy {
public:
int doOperation(int a, int b) override { return a + b; }
};
class OperationSubtract : public Strategy {
public:
int doOperation(int a, int b) override { return a - b; }
};
class Context {
Strategy* strategy;
public:
Context(Strategy* s) : strategy(s) {}
int executeStrategy(int a, int b) { return strategy->doOperation(a, b); }
};
int main(){
Context context(new OperationAdd());
cout << "10 + 5 = " << context.executeStrategy(10, 5) << endl;
delete context.executeStrategy; // 注意管理策略对象(此处省略智能指针管理)
return 0;
}
(注:实际应用中建议用智能指针管理策略对象,此处为了简洁省略)
22. 模板方法模式 (Template Method)
意图:定义一个操作中的算法骨架,将某些步骤延迟到子类中,使得子类可以不改变算法结构的情况下重新定义算法的某些特定步骤。
C++示例:
#include <iostream>
using namespace std;
class AbstractClass {
public:
void templateMethod() {
primitiveOperation1();
primitiveOperation2();
}
virtual void primitiveOperation1() = 0;
virtual void primitiveOperation2() = 0;
virtual ~AbstractClass() {}
};
class ConcreteClass : public AbstractClass {
public:
void primitiveOperation1() override { cout << "ConcreteClass Operation1" << endl; }
void primitiveOperation2() override { cout << "ConcreteClass Operation2" << endl; }
};
int main(){
ConcreteClass cc;
cc.templateMethod();
return 0;
}
23. 访问者模式 (Visitor)
意图:将作用于某对象结构上的各元素的操作分离出来封装成独立的类,使得在不改变数据结构的前提下可以增加新的操作。
C++示例:
#include <iostream>
using namespace std;
// 前置声明
class ConcreteElementA;
class ConcreteElementB;
// 访问者接口
class Visitor {
public:
virtual void visit(ConcreteElementA* element) = 0;
virtual void visit(ConcreteElementB* element) = 0;
virtual ~Visitor() {}
};
// 元素接口
class Element {
public:
virtual void accept(Visitor* visitor) = 0;
virtual ~Element() {}
};
class ConcreteElementA : public Element {
public:
void accept(Visitor* visitor) override {
visitor->visit(this);
}
void operationA() { cout << "ConcreteElementA operation" << endl; }
};
class ConcreteElementB : public Element {
public:
void accept(Visitor* visitor) override {
visitor->visit(this);
}
void operationB() { cout << "ConcreteElementB operation" << endl; }
};
class ConcreteVisitor : public Visitor {
public:
void visit(ConcreteElementA* element) override {
cout << "Visiting ElementA: "; element->operationA();
}
void visit(ConcreteElementB* element) override {
cout << "Visiting ElementB: "; element->operationB();
}
};
int main(){
ConcreteElementA elementA;
ConcreteElementB elementB;
ConcreteVisitor visitor;
elementA.accept(&visitor);
elementB.accept(&visitor);
return 0;
}
总结
以上就是23种设计模式的详细介绍及相应的C++示例。每种模式都提供了一种解决特定设计问题的思路:
- 创建型模式(抽象工厂、建造者、工厂方法、原型、单例)主要关注对象创建;
- 结构型模式(适配器、桥接、组合、装饰、外观、享元、代理)解决对象组合问题;
- 行为型模式(责任链、命令、解释器、迭代器、中介、备忘录、观察者、状态、策略、模板方法、访问者)则侧重于对象间的通信与职责分配。
通过掌握这些模式及其C++实现,你可以在软件开发中更加灵活地应对变化、降低耦合并提高系统的可维护性。