跳到主要内容C++中23种设计模式的实现速览 | 极客日志C++
C++中23种设计模式的实现速览
梳理了23种经典设计模式在C++下的实现,包括单例、工厂、观察者、策略等常用模式,并给出了简洁的代码示例。适合快速回顾或面试准备。
虚拟内存2 浏览 设计模式是解决软件设计中常见问题的可复用方案。GoF的23种模式分为创建型、结构型和行为型,下面结合C++特性,把它们的核心实现串一遍。代码里有一些简化的地方,生产环境使用时得结合场景调整,尤其是线程安全和资源管理。
创建型模式 (5个)
单例模式
确保全局只有一个实例,常用于配置管理器或日志。控制构造和拷贝很简单,但要小心多线程。
class Singleton {
private:
static Singleton* instance;
Singleton() {}
public:
static Singleton* getInstance() {
if (instance == nullptr) {
instance = new Singleton();
}
return instance;
}
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
};
实际项目里,用局部静态变量会更干净,C++11以上还能保证线程安全。
工厂方法模式
定义一个创建对象的接口,但让子类决定具体实例化哪个类。客户端不用知道具体产品类,扩展新产品时只需增加子类。
class Product {
public:
virtual ~Product() {}
virtual void operation() = 0;
};
class ConcreteProductA : public Product {
public:
void operation() override { cout << "Product A" << endl; }
};
{
:
~() {}
= ;
};
: Creator {
:
{
();
}
};
class
Creator
public
virtual
Creator
virtual Product* factoryMethod()
0
class
ConcreteCreatorA
public
public
Product* factoryMethod() override
return
new
ConcreteProductA
抽象工厂模式
提供一个创建一系列相关或依赖对象的接口,无需指定它们具体的类。适合产品族一起变化的情况。
class AbstractProductA {
public:
virtual ~AbstractProductA() {}
virtual void operationA() = 0;
};
class AbstractFactory {
public:
virtual AbstractProductA* createProductA() = 0;
virtual AbstractProductB* createProductB() = 0;
};
class ConcreteFactory1 : public AbstractFactory {
public:
AbstractProductA* createProductA() override { return new ConcreteProductA1(); }
AbstractProductB* createProductB() override { return new ConcreteProductB1(); }
};
建造者模式
分步骤构建一个复杂对象,同样的构建过程可以创建不同的表示。当你需要一步步设置参数再产出对象时很有用。
class Product {
private:
string partA, partB;
public:
void setPartA(const string& a) { partA = a; }
void setPartB(const string& b) { partB = b; }
};
class Builder {
public:
virtual ~Builder() {}
virtual void buildPartA() = 0;
virtual void buildPartB() = 0;
virtual Product* getResult() = 0;
};
class Director {
private:
Builder* builder;
public:
Director(Builder* b) : builder(b) {}
void construct() {
builder->buildPartA();
builder->buildPartB();
}
};
原型模式
通过克隆现有实例来创建新对象,避免重复初始化。核心是写一个clone虚函数。
class Prototype {
public:
virtual ~Prototype() {}
virtual Prototype* clone() const = 0;
virtual void print() const = 0;
};
class ConcretePrototype : public Prototype {
private:
int data;
public:
ConcretePrototype(int d) : data(d) {}
Prototype* clone() const override { return new ConcretePrototype(*this); }
void print() const override { cout << "Data: " << data << endl; }
};
结构型模式 (7个)
适配器模式
让不兼容的接口能一起工作。比如要把一个老接口包装成新接口暴露出去。
class Target {
public:
virtual ~Target() {}
virtual void request() { cout << "Target request" << endl; }
};
class Adaptee {
public:
void specificRequest() { cout << "Adaptee specific request" << endl; }
};
class Adapter : public Target {
private:
Adaptee* adaptee;
public:
Adapter(Adaptee* a) : adaptee(a) {}
void request() override { adaptee->specificRequest(); }
};
桥接模式
将抽象部分与实现部分分离,让它们可以独立变化。典型的用组合替代继承的场景。
class Implementor {
public:
virtual ~Implementor() {}
virtual void operationImpl() = 0;
};
class Abstraction {
protected:
Implementor* impl;
public:
Abstraction(Implementor* i) : impl(i) {}
virtual ~Abstraction() {}
virtual void operation() { impl->operationImpl(); }
};
组合模式
把对象组织成树形结构,使得单个对象和组合对象对外接口一致。操作单个和操作组合没有区别。
class Component {
public:
virtual ~Component() {}
virtual void operation() = 0;
virtual void add(Component*) {}
virtual void remove(Component*) {}
virtual Component* getChild(int) { return nullptr; }
};
class Leaf : public Component {
public:
void operation() override { cout << "Leaf operation" << endl; }
};
class Composite : public Component {
private:
vector<Component*> children;
public:
void operation() override {
cout << "Composite operation" << endl;
for (auto child : children) {
child->operation();
}
}
void add(Component* c) override { children.push_back(c); }
};
装饰器模式
动态地给对象添加功能,比生成子类更灵活。常用于在不修改原有类的情况下增强行为。
class Component {
public:
virtual ~Component() {}
virtual void operation() = 0;
};
class ConcreteComponent : public Component {
public:
void operation() override { cout << "ConcreteComponent operation" << endl; }
};
class Decorator : public Component {
protected:
Component* component;
public:
Decorator(Component* c) : component(c) {}
void operation() override { component->operation(); }
};
class ConcreteDecorator : public Decorator {
public:
ConcreteDecorator(Component* c) : Decorator(c) {}
void operation() override {
Decorator::operation();
addedBehavior();
}
void addedBehavior() { cout << "Added behavior" << endl; }
};
外观模式
为子系统中的一组接口提供一个统一的高层接口。简化外部调用,隐藏内部复杂性。
class SubsystemA {
public:
void operationA() { cout << "Subsystem A operation" << endl; }
};
class SubsystemB {
public:
void operationB() { cout << "Subsystem B operation" << endl; }
};
class Facade {
private:
SubsystemA* a;
SubsystemB* b;
public:
Facade() : a(new SubsystemA()), b(new SubsystemB()) {}
void operation() {
a->operationA();
b->operationB();
}
};
享元模式
运用共享技术有效支持大量细粒度对象。把不变的状态放在内部共享,变的外部传入。
class Flyweight {
public:
virtual ~Flyweight() {}
virtual void operation(int extrinsicState) = 0;
};
class ConcreteFlyweight : public Flyweight {
private:
int intrinsicState;
public:
ConcreteFlyweight(int state) : intrinsicState(state) {}
void operation(int extrinsicState) override {
cout << "Intrinsic: " << intrinsicState << ", Extrinsic: " << extrinsicState << endl;
}
};
class FlyweightFactory {
private:
unordered_map<int, Flyweight*> flyweights;
public:
Flyweight* getFlyweight(int key) {
if (flyweights.find(key) == flyweights.end()) {
flyweights[key] = new ConcreteFlyweight(key);
}
return flyweights[key];
}
};
代理模式
为另一个对象提供一个替身或占位符,以控制对它的访问。常见的有延迟加载、权限控制等。
class Subject {
public:
virtual ~Subject() {}
virtual void request() = 0;
};
class RealSubject : public Subject {
public:
void request() override { cout << "RealSubject request" << endl; }
};
class Proxy : public Subject {
private:
RealSubject* realSubject;
public:
Proxy() : realSubject(nullptr) {}
void request() override {
if (realSubject == nullptr) {
realSubject = new RealSubject();
}
realSubject->request();
}
};
行为型模式 (11个)
责任链模式
多个处理器依次尝试处理请求,直到某个处理器处理为止。解耦发送者和接收者。
class Handler {
protected:
Handler* successor;
public:
Handler() : successor(nullptr) {}
virtual ~Handler() {}
void setSuccessor(Handler* s) { successor = s; }
virtual void handleRequest(int request) = 0;
};
class ConcreteHandler1 : public Handler {
public:
void handleRequest(int request) override {
if (request < 10) {
cout << "Handler1 handled request " << request << endl;
} else if (successor != nullptr) {
successor->handleRequest(request);
}
}
};
命令模式
将请求封装成对象,以便参数化客户端、记录操作日志或实现撤销。
class Receiver {
public:
void action() { cout << "Receiver action" << endl; }
};
class Command {
public:
virtual ~Command() {}
virtual void execute() = 0;
};
class ConcreteCommand : public Command {
private:
Receiver* receiver;
public:
ConcreteCommand(Receiver* r) : receiver(r) {}
void execute() override { receiver->action(); }
};
class Invoker {
private:
Command* command;
public:
void setCommand(Command* c) { command = c; }
void executeCommand() { command->execute(); }
};
解释器模式
给定一个语言,定义其文法表示,并构建解释器来解释句子。实际项目中不太常用。
class Context {};
class Expression {
public:
virtual ~Expression() {}
virtual bool interpret(Context& context) = 0;
};
class TerminalExpression : public Expression {
public:
bool interpret(Context& context) override {
return true;
}
};
迭代器模式
提供一种方法顺序访问聚合对象中的各个元素,而无需暴露其内部结构。C++标准库的迭代器用得很多。
template<typename T>
class Iterator {
public:
virtual ~Iterator() {}
virtual T next() = 0;
virtual bool hasNext() = 0;
};
template<typename T>
class ConcreteIterator : public Iterator<T> {
private:
vector<T> collection;
size_t position;
public:
ConcreteIterator(const vector<T>& col) : collection(col), position(0) {}
T next() override { return collection[position++]; }
bool hasNext() override { return position < collection.size(); }
};
中介者模式
用一个中介对象封装一系列对象的交互,减少对象之间的直接引用。对象只需知道中介者。
class Colleague;
class Mediator {
public:
virtual ~Mediator() {}
virtual void notify(Colleague* sender, string event) = 0;
};
class Colleague {
protected:
Mediator* mediator;
public:
Colleague(Mediator* m = nullptr) : mediator(m) {}
void setMediator(Mediator* m) { mediator = m; }
};
class ConcreteColleague1 : public Colleague {
public:
void doSomething() {
mediator->notify(this, "event1");
}
};
备忘录模式
在不破坏封装的前提下,捕获并保存一个对象的内部状态,以便后续恢复。
class Memento {
private:
string state;
public:
Memento(const string& s) : state(s) {}
string getState() const { return state; }
};
class Originator {
private:
string state;
public:
void setState(const string& s) { state = s; }
string getState() const { return state; }
Memento* createMemento() { return new Memento(state); }
void restoreMemento(Memento* m) { state = m->getState(); }
};
观察者模式
定义对象间一对多的依赖关系,当一个对象状态改变时,所有依赖它的对象都会收到通知。事件驱动的基础。
class Observer {
public:
virtual ~Observer() {}
virtual void update(float temperature) = 0;
};
class Subject {
private:
vector<Observer*> observers;
public:
void attach(Observer* o) { observers.push_back(o); }
void detach(Observer* o) { }
void notify(float temperature) {
for (auto observer : observers) {
observer->update(temperature);
}
}
};
class ConcreteObserver : public Observer {
public:
void update(float temperature) override {
cout << "Temperature updated: " << temperature << endl;
}
};
状态模式
允许对象在其内部状态改变时改变它的行为,看起来好像修改了它的类。
class Context;
class State {
public:
virtual ~State() {}
virtual void handle(Context* context) = 0;
};
class Context {
private:
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;
};
策略模式
定义一系列算法,把它们封装起来,并且可以相互替换。可以避免大量 if-else 或 switch。
class Strategy {
public:
virtual ~Strategy() {}
virtual void algorithm() = 0;
};
class ConcreteStrategyA : public Strategy {
public:
void algorithm() override { cout << "Strategy A algorithm" << endl; }
};
class Context {
private:
Strategy* strategy;
public:
Context(Strategy* s) : strategy(s) {}
void setStrategy(Strategy* s) { strategy = s; }
void executeStrategy() { strategy->algorithm(); }
};
模板方法模式
在一个方法中定义算法的骨架,将某些步骤延迟到子类中实现。子类可以改变某些步骤,但不能改变整体流程。
class AbstractClass {
public:
virtual ~AbstractClass() {}
void templateMethod() {
primitiveOperation1();
primitiveOperation2();
}
virtual void primitiveOperation1() = 0;
virtual void primitiveOperation2() = 0;
};
class ConcreteClass : public AbstractClass {
public:
void primitiveOperation1() override { cout << "Concrete operation 1" << endl; }
void primitiveOperation2() override { cout << "Concrete operation 2" << endl; }
};
访问者模式
表示一个作用于某对象结构中的各元素的操作,使你可以在不改变元素类的前提下定义作用于这些元素的新操作。
class ConcreteElementA;
class ConcreteElementB;
class Visitor {
public:
virtual ~Visitor() {}
virtual void visit(ConcreteElementA* element) = 0;
virtual void visit(ConcreteElementB* element) = 0;
};
class Element {
public:
virtual ~Element() {}
virtual void accept(Visitor* visitor) = 0;
};
class ConcreteElementA : public Element {
public:
void accept(Visitor* visitor) override { visitor->visit(this); }
void operationA() { cout << "Operation A" << endl; }
};
实际开发中优先掌握的
上面23种模式看起来不少,但高频出现的也就那么几个。下面这些最好先弄熟:
- 单例模式:全局唯一实例,配置、日志都离不开它。
- 工厂方法:解耦对象创建,简单扩展。
- 观察者模式:事件通知、消息机制的基础。
- 策略模式:算法替换,干掉大片条件判断。
- 装饰器模式:运行时动态加功能,比继承灵活。
其次适配器、代理、模板方法、命令和外观也经常遇到。理解每种模式适合的场景比背代码重要,过度设计反而是负担。有些实现可以用C++11/14/17的特性简化,比如智能指针、lambda配合命令模式,或者用局部静态变量实现线程安全的单例。这些模式本身是思想,C++的具体写法可以很现代。
相关免费在线工具
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
- Markdown转HTML
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
- HTML转Markdown
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
- JSON 压缩
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
- JSON美化和格式化
将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online