设计模式C++举例

面向对象设计模式是为了解决特定问题而在一定场景下总结出的可重用的解决方案。它们帮助开发者编写灵活、可维护和可复用的代码。设计模式通常分为三大类:创建型、结构型和行为型。

一、创建型模式

这些模式提供了对象创建机制的增强,使得创建对象更加灵活、清晰。

工厂方法(Factory Method)

定义一个用于创建对象的接口,让子类决定实例化哪一个类。
场景:一个日志系统,支持多种类型的日志输出,例如文件日志和控制台日志。
实现


#include <iostream>
#include <memory>

class Logger {
public:
virtual void log(const std::string& message) = 0;
virtual ~Logger() {}
};

class FileLogger : public Logger {
public:
void log(const std::string& message) override {
    std::cout << "File log: " << message << std::endl;
}
};

class ConsoleLogger : public Logger {
public:
void log(const std::string& message) override {
    std::cout << "Console log: " << message << std::endl;
}
};

class LoggerFactory {
public:
virtual std::unique_ptr<Logger> createLogger() = 0;
virtual ~LoggerFactory() {}
};

class FileLoggerFactory : public LoggerFactory {
public:
std::unique_ptr<Logger> createLogger() override {
    return std::make_unique<FileLogger>();
}
};

class ConsoleLoggerFactory : public LoggerFactory {
public:
std::unique_ptr<Logger> createLogger() override {
    return std::make_unique<ConsoleLogger>();
}
};

// 使用
int main() {
    std::unique_ptr<LoggerFactory> fileLoggerFactory = std::make_unique<FileLoggerFactory>();
    auto fileLogger = fileLoggerFactory->createLogger();
    fileLogger->log("This is a file logger message.");

    std::unique_ptr<LoggerFactory> consoleLoggerFactory = std::make_unique<ConsoleLoggerFactory>();
    auto consoleLogger = consoleLoggerFactory->createLogger();
    consoleLogger->log("This is a console logger message.");

    return 0;
}

抽象工厂(Abstract Factory)

提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
场景:一个跨平台的UI库,需要根据不同的操作系统创建相应的UI控件。
实现

#include <iostream>
#include <memory>

class Button {
public:
virtual void paint() = 0;
virtual ~Button() {}
};

class WindowsButton : public Button {
public:
void paint() override {
    std::cout << "Windows Button\n";
}
};

class MacOSButton : public Button {
public:
void paint() override {
    std::cout << "MacOS Button\n";
}
};

class GUIFactory {
public:
virtual std::unique_ptr<Button> createButton() = 0;
virtual ~GUIFactory() {}
};

class WindowsFactory : public GUIFactory {
public:
std::unique_ptr<Button> createButton() override {
    return std::make_unique<WindowsButton>();
}
};

class MacOSFactory : public GUIFactory {
public:
std::unique_ptr<Button> createButton() override {
    return std::make_unique<MacOSButton>();
}
};

// 使用
int main() {
    std::unique_ptr<GUIFactory> guiFactory;
    std::unique_ptr<Button> button;

    guiFactory = std::make_unique<WindowsFactory>();
    button = guiFactory->createButton();
    button->paint();

    guiFactory = std::make_unique<MacOSFactory>();
    button = guiFactory->createButton();
    button->paint();

    return 0;
}

建造者(Builder)

使用多个简单的对象一步步构建成一个复杂的对象。
场景:构建一个复杂的汽车对象,包括引擎、轮胎和座椅等部件。
实现

#include <iostream>
#include <string>

class Car {
public:
void setEngine(const std::string& engine) {
    this->engine = engine;
}
void setTires(const std::string& tires) {
    this->tires = tires;
}
void setSeats(const std::string& seats) {
    this->seats = seats;
}
void show() {
    std::cout << "Car with " << engine << ", " << tires << ", " << seats << std::endl;
}
private:
std::string engine, tires, seats;
};

class CarBuilder {
public:
virtual void buildEngine() = 0;
virtual void buildTires() = 0;
virtual void buildSeats() = 0;
virtual Car getCar() = 0;
virtual ~CarBuilder() {}
};

class SportsCarBuilder : public CarBuilder {
public:
void buildEngine() override {
    car.setEngine("Sports Engine");
}
void buildTires() override {
    car.setTires("Sports Tires");
}
void buildSeats() override {
    car.setSeats("Sports Seats");
}
Car getCar() override {
    return car;
}
private:
Car car;
};

class Director {
public:
void construct(CarBuilder& builder) {
    builder.buildEngine();
    builder.buildTires();
    builder.buildSeats();
}
};

// 使用
int main() {
    SportsCarBuilder builder;
    Director director;

    director.construct(builder);
    Car car = builder.getCar();
    car.show();

    return 0;
}

请注意,为了简化,示例中的一些实现细节被省略了。在实际应用中,你可能需要根据具体需求添加更多的功能和细节。

原型模式(Prototype)

通过复制现有的实例来创建新的实例,而不是通过新建类。
场景:在图形编辑器中,需要复制(克隆)图形对象。图形对象的创建成本较高,因此直接复制现有对象比重新创建更有效率。
实现

cppCopy code
#include <iostream>
#include <unordered_map>
#include <string>
#include <memory>

// 抽象原型类
class Shape {
public:
    virtual std::shared_ptr<Shape> clone() const = 0;
    virtual void draw() const = 0;
    virtual ~Shape() {}
};

// 具体原型类
class Rectangle : public Shape {
public:
    std::shared_ptr<Shape> clone() const override {
        return std::make_shared<Rectangle>(*this);
    }
    void draw() const override {
        std::cout << "Drawing Rectangle\n";
    }
};

class Circle : public Shape {
public:
    std::shared_ptr<Shape> clone() const override {
        return std::make_shared<Circle>(*this);
    }
    void draw() const override {
        std::cout << "Drawing Circle\n";
    }
};

// 使用原型管理器简化原型对象的访问
class PrototypeManager {
private:
    std::unordered_map<std::string, std::shared_ptr<Shape>> prototypes;
public:
    PrototypeManager() {
        prototypes["rectangle"] = std::make_shared<Rectangle>();
        prototypes["circle"] = std::make_shared<Circle>();
    }
    std::shared_ptr<Shape> getPrototype(const std::string& shapeType) {
        if (prototypes.find(shapeType) != prototypes.end()) {
            return prototypes[shapeType]->clone();
        }
        return nullptr;
    }
};

// 使用
int main() {
    PrototypeManager manager;
    auto rect = manager.getPrototype("rectangle");
    if (rect) rect->draw();

    auto circle = manager.getPrototype("circle");
    if (circle) circle->draw();

    return 0;
}

在这个例子中,RectangleCircle类都实现了Shape接口,并提供了clone方法来复制自身。PrototypeManager类管理所有原型对象,使得客户端可以轻松地访问和复制任意类型的图形对象。

单例模式(Singleton)

确保一个类只有一个实例,并提供全局访问点。
场景:全局配置管理器,整个应用程序中只应存在一个配置管理器实例。
实现

cppCopy code
#include <iostream>
#include <mutex>

class Singleton {
private:
    static Singleton* instance;
    static std::mutex mutex;

protected:
    Singleton() = default; // 私有构造函数

public:
    Singleton(const Singleton&) = delete; // 防止拷贝
    Singleton& operator=(const Singleton&) = delete; // 防止赋值

    static Singleton* getInstance() {
        std::lock_guard<std::mutex> lock(mutex);
        if (instance == nullptr) {
            instance = new Singleton();
        }
        return instance;
    }
};

Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mutex;

// 使用
int main() {
    Singleton* s1 = Singleton::getInstance();
    Singleton* s2 = Singleton::getInstance();

    std::cout << "Singleton Test: " << (s1 == s2) << std::endl; // 输出:1

    return 0;
}

在这个例子中,Singleton类通过私有构造函数、删除的拷贝构造函数和赋值运算符确保了只能创建一个实例。getInstance方法提供了对这个唯一实例的全局访问点,并且使用互斥锁确保了在多线程环境中的线程安全。
这两个模式,原型模式和单例模式,分别在对象复制和实例唯一性管理方面提供了设计上的优势,使得代码更加灵活和可维护。

二、结构型模式

这些模式涉及到类和对象的组合,用于形成更大的结构。

  • 适配器(Adapter):允许不兼容的接口能够一起工作。
  • 桥接(Bridge):将抽象部分与实现部分分离,使它们可以独立变化。
  • 组合(Composite):将对象组合成树形结构以表示“部分-整体”的层次结构。
  • 装饰(Decorator):动态地给一个对象添加一些额外的职责。
  • 外观(Facade):为子系统中的一组接口提供一个一致的界面。
  • 享元(Flyweight):运用共享技术有效地支持大量细粒度对象的复用。
  • 代理(Proxy):为其他对象提供一种代理以控制对这个对象的访问。

适配器(Adapter)

允许不兼容的接口能够一起工作。
场景:假设有一个旧的图形界面类库中的Rectangle类,我们在新的系统中使用了一个不兼容的Shape接口。我们希望能够使用Rectangle类作为Shape的实现。
实现


// 目标接口
class Shape {
public:
virtual void draw() = 0;
virtual ~Shape() {}
};

// 旧的不兼容类
class Rectangle {
public:
void drawRectangle() {
    std::cout << "Rectangle draw.\n";
}
};

// 适配器
class RectangleAdapter : public Shape {
private:
Rectangle* rectangle;
public:
RectangleAdapter(Rectangle* r) : rectangle(r) {}
void draw() override {
    rectangle->drawRectangle();
}
};

// 使用
int main() {
    Rectangle* oldRectangle = new Rectangle();
    Shape* rectangle = new RectangleAdapter(oldRectangle);
    rectangle->draw(); // 使用适配器使旧的Rectangle类兼容Shape接口
    delete rectangle;
    delete oldRectangle;
    return 0;
}

桥接(Bridge)

将抽象部分与实现部分分离,使它们可以独立变化。
场景:如果有多种图形对象,并且每种图形都可以使用不同的绘制API进行绘制,我们可以将图形对象的抽象部分与其绘制的实现部分分离开来。
实现


// 实现接口
class DrawingAPI {
public:
virtual void drawCircle(double x, double y, double radius) = 0;
virtual ~DrawingAPI() {}
};

// 具体实现A
class DrawingAPI1 : public DrawingAPI {
public:
void drawCircle(double x, double y, double radius) override {
    std::cout << "API1.circle at " << x << ':' << y << ' ' << radius << std::endl;
}
};

// 具体实现B
class DrawingAPI2 : public DrawingAPI {
public:
void drawCircle(double x, double y, double radius) override {
    std::cout << "API2.circle at " << x << ':' << y << ' ' << radius << std::endl;
}
};

// 抽象
class Shape {
protected:
DrawingAPI* drawingAPI;
Shape(DrawingAPI* drawingAPI) : drawingAPI(drawingAPI) {}
public:
virtual void draw() = 0; // 低层操作
virtual ~Shape() {}
};

// 具体的抽象
class CircleShape : public Shape {
private:
double x, y, radius;
public:
CircleShape(double x, double y, double radius, DrawingAPI* drawingAPI) : 
Shape(drawingAPI), x(x), y(y), radius(radius) {}
void draw() override {
    drawingAPI->drawCircle(x, y, radius);
}
};

// 使用
int main() {
    CircleShape circle1(1, 2, 3, new DrawingAPI1());
    CircleShape circle2(5, 7, 11, new DrawingAPI2());
    circle1.draw();
    circle2.draw();
    return 0;
}

组合(Composite)

将对象组合成树形结构以表示“部分-整体”的层次结构。
场景:设计一个图形界面组件库,其中 **Component **是基础接口,既可以代表单个组件也可以代表一组组件。
实现

#include <iostream>
#include <vector>
#include <memory>

// 组件基类
class Component {
public:
virtual void draw() = 0;
virtual void add(const std::shared_ptr<Component>& component) {}
virtual ~Component() {}
};

// 叶子组件
class Leaf : public Component {
public:
void draw() override {
    std::cout << "Leaf draw.\n";
}
};

// 容器组件
class Composite : public Component {
private:
std::vector<std::shared_ptr<Component>> children;
public:
void draw() override {
    for (auto& child : children) {
        child->draw();
    }
}
void add(const std::shared_ptr<Component>& component) override {
    children.push_back(component);
}
};

// 使用
int main() {
    auto composite = std::make_shared<Composite>();
    auto leaf1 = std::make_shared<Leaf>();
    auto leaf2 = std::make_shared<Leaf>();

    composite->add(leaf1);
    composite->add(leaf2);

    composite->draw(); // 绘制组合对象及其子对象
    return 0;
}

装饰(Decorator)

动态地给一个对象添加一些额外的职责。
场景:给文本消息添加多种格式装饰(例如,加粗、斜体)。
实现


#include <iostream>
#include <string>

// 组件接口
class Text {
public:
virtual std::string getContent() const = 0;
virtual ~Text() {}
};

// 具体组件
class PlainText : public Text {
private:
std::string text;
public:
PlainText(const std::string& text) : text(text) {}
std::string getContent() const override {
    return text;
}
};

// 装饰器基类
class TextDecorator : public Text {
protected:
Text* wrappedText;
public:
TextDecorator(Text* text) : wrappedText(text) {}
virtual ~TextDecorator() {
    delete wrappedText;
}
};

// 具体装饰器
class BoldDecorator : public TextDecorator {
public:
BoldDecorator(Text* text) : TextDecorator(text) {}
std::string getContent() const override {
    return "<b>" + wrappedText->getContent() + "</b>";
}
};

class ItalicDecorator : public TextDecorator {
public:
ItalicDecorator(Text* text) : TextDecorator(text) {}
std::string getContent() const override {
    return "<i>" + wrappedText->getContent() + "</i>";
}
};

// 使用
int main() {
    Text* plainText = new PlainText("Hello, World!");
    Text* boldText = new BoldDecorator(plainText);
    Text* boldItalicText = new ItalicDecorator(boldText);

    std::cout << boldItalicText->getContent() << std::endl; // 输出: <i><b>Hello, World!</b></i>

    delete boldItalicText; // 注意:这将递归删除所有装饰器和包装的对象
    return 0;
}

外观(Facade)

为子系统中的一组接口提供一个一致的界面。
场景:为复杂的子系统(例如,计算机的启动过程)提供一个简单的接口。
实现

#include <iostream>

// 子系统类
class CPU {
public:
void start() {
    std::cout << "CPU starts.\n";
}
};

class Memory {
public:
void load() {
    std::cout << "Memory loads.\n";
}
};

class HardDrive {
public:
void read() {
    std::cout << "Hard drive reads.\n";
}
};

// 外观
class ComputerFacade {
private:
CPU cpu;
Memory memory;
HardDrive hardDrive;
public:
void start() {
    cpu.start();
    memory.load();
    hardDrive.read();
    std::cout << "Computer starts successfully.\n";
}
};

// 使用
int main() {
    ComputerFacade computer;
    computer.start(); // 通过外观类简化了复杂子系统的启动过程
    return 0;
}

享元(Flyweight)

运用共享技术有效地支持大量细粒度对象的复用。
场景:在文本编辑器中,大量重复使用字符对象。
实现

#include <iostream>
#include <map>
#include <string>

// 享元
class Character {
private:
char glyph;
public:
Character(char glyph) : glyph(glyph) {}
void draw() {
    std::cout << glyph;
}
};

// 享元工厂
class CharacterFactory {
private:
std::map<char, Character*> characters;
public:
~CharacterFactory() {
    for (auto it : characters) {
        delete it.second;
    }
}
Character* getCharacter(char key) {
    if (characters.find(key) == characters.end()) {
        characters[key] = new Character(key);
    }
    return characters[key];
}
};

// 使用
int main() {
    CharacterFactory factory;
    std::string document = "aaabbc";
    for (char c : document) {
        Character* character = factory.getCharacter(c);
        character->draw();
    }
    return 0;
}

代理(Proxy)

为其他对象提供一种代理以控制对这个对象的访问。
场景:控制对敏感对象的访问,例如,一个重要文档的访问权限控制。
实现

#include <iostream>
#include <string>

// 主题接口
class Document {
public:
virtual void display() = 0;
virtual ~Document() {}
};

// 真实主题
class RealDocument : public Document {
private:
std::string content;
public:
RealDocument(const std::string& content) : content(content) {}
void display() override {
    std::cout << "Displaying Document: " << content << std::endl;
}
};

// 代理
class ProxyDocument : public Document {
private:
RealDocument* realDocument;
std::string content;
public:
ProxyDocument(const std::string& content) : realDocument(nullptr), content(content) {}
~ProxyDocument() {
    delete realDocument;
}
void display() override {
    if (realDocument == nullptr) {
        realDocument = new RealDocument(content);
    }
    realDocument->display();
}
};

// 使用
int main() {
    ProxyDocument proxy("Some sensitive information");
    proxy.display(); // 真实文档对象只有在需要时才被创建和显示
    return 0;
}

以上是适配器、桥接、组合、装饰、外观、享元和代理设计模式的C++实现示例。每种模式都解决了特定的软件设计问题,帮助开发者编写更加灵活、可维护的代码。

三、行为型模式

这些模式特别关注对象之间的通信。

  • 责任链(Chain of Responsibility):为请求创建一个接收者对象的链。
  • 命令(Command):将请求封装成对象,从而允许使用不同的请求、队列或日志来参数化其他对象。
  • 解释器(Interpreter):给定一个语言,定义它的文法的一种表示,并定义一个解释器,使用该解释器来解释语言中的句子。
  • 迭代器(Iterator):提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露其内部的表示。
  • 中介者(Mediator):用一个中介对象来封装一系列对象交互。
  • 备忘录(Memento):在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
  • 观察者(Observer):当一个对象状态发生变化时,所有依赖于它的对象都得到通知并被自动更新。
  • 状态(State):允许一个对象在其内部状态改变时改变它的行为。
  • 策略(Strategy):定义一系列的算法,把它们一个个封装起来,并使它们可相互替换。
  • 模板方法(Template Method):在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。
  • 访问者(Visitor):表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变元素的类的前提下定义作用于这些元素的新操作。

每种设计模式解决特定问题的范围和方式各不相同,选择合适的设计模式可以帮助开发高质量的软件。

责任链(Chain of Responsibility)

为请求创建一个接收者对象的链。
场景:日志系统,不同级别的日志消息由不同的处理器处理。
实现

#include <iostream>
#include <string>

class Logger {
protected:
int level;
Logger* nextLogger;
public:
static const int INFO = 1;
static const int DEBUG = 2;
static const int ERROR = 3;

void setNextLogger(Logger* nextLogger) {
    this->nextLogger = nextLogger;
}

void logMessage(int level, const std::string& message) {
    if (this->level <= level) {
        write(message);
    }
    if (nextLogger != nullptr) {
        nextLogger->logMessage(level, message);
    }
}

protected:
virtual void write(const std::string& message) = 0;
};

class ConsoleLogger : public Logger {
public:
ConsoleLogger(int level) {
    this->level = level;
}

protected:
void write(const std::string& message) override {
    std::cout << "Standard Console::Logger: " << message << std::endl;
}
};

class ErrorLogger : public Logger {
public:
ErrorLogger(int level) {
    this->level = level;
}

protected:
void write(const std::string& message) override {
    std::cout << "Error Console::Logger: " << message << std::endl;
}
};

class FileLogger : public Logger {
public:
FileLogger(int level) {
    this->level = level;
}

protected:
void write(const std::string& message) override {
    std::cout << "File::Logger: " << message << std::endl;
}
};

// 使用
int main() {
    Logger* errorLogger = new ErrorLogger(Logger::ERROR);
    Logger* fileLogger = new FileLogger(Logger::DEBUG);
    Logger* consoleLogger = new ConsoleLogger(Logger::INFO);

    errorLogger->setNextLogger(fileLogger);
    fileLogger->setNextLogger(consoleLogger);

    errorLogger->logMessage(Logger::INFO, "This is an information.");
    errorLogger->logMessage(Logger::DEBUG, "This is a debug level information.");
    errorLogger->logMessage(Logger::ERROR, "This is an error information.");

    delete errorLogger;
    delete fileLogger;
    delete consoleLogger;

    return 0;
}

命令(Command)

将请求封装成对象,从而允许使用不同的请求、队列或日志来参数化其他对象。
场景:实现一个简单的遥控器,可以控制家电的开和关。
实现

#include <iostream>
#include <vector>
#include <memory>

// 命令接口
class Command {
public:
virtual void execute() = 0;
virtual ~Command() {}
};

// 接收者
class Light {
public:
void on() {
    std::cout << "Light is on\n";
}
void off() {
    std::cout << "Light is off\n";
}
};

// 具体命令
class LightOnCommand : public Command {
private:
Light* light;
public:
LightOnCommand(Light* light) : light(light) {}
void execute() override {
    light->on();
}
};

class LightOffCommand : public Command {
private:
Light* light;
public:
LightOffCommand(Light* light) : light(light) {}
void execute() override {
    light->off();
}
};

// 调用者
class RemoteControl {
private:
Command* command;
public:
void setCommand(Command* command) {
    this->command = command;
}
void pressButton() {
    command->execute();
}
};

// 使用
int main() {
    Light* light = new Light();
    Command* lightOn = new LightOnCommand(light);
    Command* lightOff = new LightOffCommand(light);

    RemoteControl* control = new RemoteControl();
    control->setCommand(lightOn);
    control->pressButton();
    control->setCommand(lightOff);
    control->pressButton();

    delete light;
    delete lightOn;
    delete lightOff;
    delete control;

    return 0;
}

解释器(Interpreter)

给定一个语言,定义它的文法的一种表示,并定义一个解释器,使用该解释器来解释语言中的句子。
场景:实现一个简单的表达式解释器,能够解释简单的加法和减法运算。
实现


#include <iostream>
#include <string>
#include <memory>

class Expression {
public:
virtual int interpret() = 0;
virtual ~Expression() {}
};

class Number : public Expression {
private:
int number;
public:
Number(int number) : number(number) {}
int interpret() override {
    return number;
}
};

class Plus : public Expression {
private:
std::shared_ptr<Expression> leftOperand;
std::shared_ptr<Expression> rightOperand;
public:
Plus(std::shared_ptr<Expression> left, std::shared_ptr<Expression> right) : leftOperand(left), rightOperand(right) {}
int interpret() override {
    return leftOperand->interpret() + rightOperand->interpret();
}
};

class Minus : public Expression {
private:
std::shared_ptr<Expression> leftOperand;
std::shared_ptr<Expression> rightOperand;
public:
Minus(std::shared_ptr<Expression> left, std::shared_ptr<Expression> right) : leftOperand(left), rightOperand(right) {}
int interpret() override {
    return leftOperand->interpret() - rightOperand->interpret();
}
};

// 使用
int main() {
    std::shared_ptr<Expression> expression = std::make_shared<Plus>(std::make_shared<Number>(5), std::make_shared<Number>(3));
    std::cout << expression->interpret() << std::endl; // 输出: 8

    expression = std::make_shared<Minus>(std::make_shared<Number>(5), std::make_shared<Number>(3));
    std::cout << expression->interpret() << std::endl; // 输出: 2

    return 0;
}

迭代器(Iterator)

提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露其内部的表示。
场景:实现一个容器类,支持对容器中的元素进行顺序访问,而不暴露其内部表示。
实现

#include <iostream>
#include <vector>

template<typename T>
class Iterator {
public:
virtual bool hasNext() = 0;
virtual T next() = 0;
};

template<typename T>
class Container {
public:
virtual Iterator<T>* createIterator() = 0;
};

template<typename T>
class ConcreteContainer : public Container<T> {
private:
std::vector<T> elements;
public:
void add(T element) {
    elements.push_back(element);
}

class ConcreteIterator : public Iterator<T> {
private:
ConcreteContainer& container;
size_t currentIndex;
public:
ConcreteIterator(ConcreteContainer& container) : container(container), currentIndex(0) {}

bool hasNext() override {
    return currentIndex < container.elements.size();
}

T next() override {
    return container.elements[currentIndex++];
}
};

Iterator<T>* createIterator() override {
    return new ConcreteIterator(*this);
}
};

// 使用
int main() {
    ConcreteContainer<int> container;
    container.add(1);
    container.add(2);
    container.add(3);

    Iterator<int>* it = container.createIterator();
    while (it->hasNext()) {
        std::cout << it->next() << std::endl;
    }
    delete it;

    return 0;
}

中介者(Mediator)

用一个中介对象来封装一系列对象交互。
场景:实现一个聊天室,允许多个用户发送消息,消息通过中介者(聊天室)进行传递。
实现

#include <iostream>
#include <string>
#include <vector>

class Colleague;

class Mediator {
public:
virtual void send(const std::string& message, Colleague* colleague) = 0;
};

class Colleague {
protected:
Mediator* mediator;
public:
Colleague(Mediator* mediator) : mediator(mediator) {}
virtual void send(const std::string& message) = 0;
virtual void receive(const std::string& message) = 0;
};

class ConcreteMediator : public Mediator {
private:
std::vector<Colleague*> colleagues;
public:
void addColleague(Colleague* colleague) {
    colleagues.push_back(colleague);
}
void send(const std::string& message, Colleague* colleague) override {
    for (auto& c : colleagues) {
        if (c != colleague) {
            c->receive(message);
        }
    }
}
};

class ConcreteColleague : public Colleague {
private:
    std::string name;
public:
    ConcreteColleague(Mediator* mediator, const std::string& name) : Colleague(mediator), name(name) {}
    void send(const std::string& message) override {
        mediator->send(name + ": " + message, this);
    }
    void receive(const std::string& message) override {
        std::cout << name << " receives: " << message << std::endl;
    }
};

// 使用
int main() {
    ConcreteMediator mediator;
    ConcreteColleague colleague1(&mediator, "John");
    ConcreteColleague colleague2(&mediator, "Jane");

    mediator.addColleague(&colleague1);
    mediator.addColleague(&colleague2);

    colleague1.send("Hi there!");
    colleague2.send("Hello!");

    return 0;
}

备忘录(Memento)

在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
场景:实现一个文本编辑器的撤销功能,允许用户恢复到之前的状态。
实现

#include <iostream>
#include <string>
#include <memory>
#include <stack>

class Memento {
std::string state;
public:
Memento(const std::string& state) : state(state) {}
std::string getState() const { return state; }
};

class Originator {
std::string state;
public:
void setState(const std::string& state) { this->state = state; }
std::string getState() const { return state; }
std::shared_ptr<Memento> saveStateToMemento() { return std::make_shared<Memento>(state); }
void getStateFromMemento(const std::shared_ptr<Memento>& memento) { state = memento->getState(); }
};

class Caretaker {
std::stack<std::shared_ptr<Memento>> mementoStack;
public:
void add(const std::shared_ptr<Memento>& state) { mementoStack.push(state); }
std::shared_ptr<Memento> get() { 
    auto lastState = mementoStack.top();
    mementoStack.pop();
    return lastState;
}
};

// 使用
int main() {
    Originator originator;
    Caretaker caretaker;

    originator.setState("State #1");
    originator.setState("State #2");
    caretaker.add(originator.saveStateToMemento());

    originator.setState("State #3");
    std::cout << "Current State: " << originator.getState() << std::endl;
    originator.getStateFromMemento(caretaker.get());
    std::cout << "First saved State: " << originator.getState() << std::endl;

    return 0;
}

观察者(Observer)

当一个对象状态发生变化时,所有依赖于它的对象都得到通知并被自动更新。
场景:实现一个简单的新闻订阅系统,当有新新闻发布时,所有订阅者都会收到通知。
实现

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

class Observer {
public:
virtual void update(const std::string& message) = 0;
};

class Subject {
std::vector<Observer*> observers;
public:
void attach(Observer* observer) { observers.push_back(observer); }
void detach(Observer* observer) {
    observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());
}
void notify(const std::string& message) {
    for (auto& observer : observers) {
        observer->update(message);
    }
}
};

class NewsAgency : public Subject {};

class Subscriber : public Observer {
std::string name;
public:
Subscriber(const std::string& name) : name(name) {}
void update(const std::string& message) override {
    std::cout << name << " received news: " << message << std::endl;
}
};

// 使用
int main() {
    NewsAgency agency;
    Subscriber sub1("Alice"), sub2("Bob");

    agency.attach(&sub1);
    agency.attach(&sub2);

    agency.notify("New edition of the newspaper is out!");

    return 0;
}

状态(State)

允许一个对象在其内部状态改变时改变它的行为。
场景:实现一个音乐播放器的状态管理,包括播放、暂停和停止状态。
实现

#include <iostream>
#include <memory>

class State {
public:
virtual void doAction() = 0;
virtual ~State() {}
};

class MusicPlayerContext {
std::shared_ptr<State> state;
public:
void setState(std::shared_ptr<State> state) {
    this->state = state;
}
void doAction() {
    state->doAction();
}
};

class PlayState : public State {
public:
void doAction() override {
    std::cout << "Music is playing\n";
}
};

class PauseState : public State {
public:
void doAction() override {
    std::cout << "Music is paused\n";
}
};

class StopState : public State {
public:
void doAction() override {
    std::cout << "Music is stopped\n";
}
};

// 使用
int main() {
    MusicPlayerContext context;

    context.setState(std::make_shared<PlayState>());
    context.doAction();

    context.setState(std::make_shared<PauseState>());
    context.doAction();

    context.setState(std::make_shared<StopState>());
    context.doAction();

    return 0;
}

策略(Strategy)

定义一系列的算法,把它们一个个封装起来,并使它们可相互替换。
场景:实现一个简单的图像过滤器应用,可以应用不同的过滤策略。
实现

#include <iostream>
#include <memory>

class FilterStrategy {
public:
virtual void apply() = 0;
virtual ~FilterStrategy() {}
};

class ImageEditor {
std::shared_ptr<FilterStrategy> filter;
public:
void setFilter(std::shared_ptr<FilterStrategy> filter) {
    this->filter = filter;
}
void applyFilter() {
    filter->apply();
}
};

class BlackAndWhiteFilter : public FilterStrategy {
public:
void apply() override {
    std::cout << "Applying Black and White Filter\n";
}
};

class SepiaFilter : public FilterStrategy {
public:
void apply() override {
    std::cout << "Applying Sepia Filter\n";
}
};

// 使用
int main() {
    ImageEditor editor;

    editor.setFilter(std::make_shared<BlackAndWhiteFilter>());
    editor.applyFilter();

    editor.setFilter(std::make_shared<SepiaFilter>());
    editor.applyFilter();

    return 0;
}

模板方法(Template Method)

在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。
场景:实现一个编译器的构建过程,包括前端处理、编译和后端处理步骤。
实现

#include <iostream>

class Compiler {
public:
void compile() {
    frontEnd();
    compileToTarget();
    backEnd();
}

protected:
virtual void frontEnd() = 0;
virtual void compileToTarget() = 0;
virtual void backEnd() = 0;
};

class CppCompiler : public Compiler {
protected:
void frontEnd() override {
    std::cout << "C++ Front End processing\n";
}
void compileToTarget() override {
    std::cout << "Compiling C++ to target\n";
}
void backEnd() override {
    std::cout << "C++ Back End processing\n";
}
};

// 使用
int main() {
    CppCompiler cppCompiler;
    cppCompiler.compile();

    return 0;
}

访问者(Visitor)

表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变元素的类的前提下定义作用于这些元素的新操作。
场景:实现一个图形对象结构,允许在不修改对象的前提下定义新的操作。
实现

#include <iostream>

class Circle;
class Rectangle;

class Visitor {
public:
virtual void visitCircle(Circle *circle) = 0;
virtual void visitRectangle(Rectangle *rectangle) = 0;
virtual ~Visitor() {}
};

class Shape {
public:
virtual void accept(Visitor *visitor) = 0;
virtual ~Shape() {}
};

class Circle : public Shape {
public:
void accept(Visitor *visitor) override {
    visitor->visitCircle(this);
}
};

class Rectangle : public Shape {
public:
void accept(Visitor *visitor) override {
    visitor->visitRectangle(this);
}
};

class DrawVisitor : public Visitor {
public:
void visitCircle(Circle *circle) override {
    std::cout << "Drawing a circle\n";
}
void visitRectangle(Rectangle *rectangle) override {
    std::cout << "Drawing a rectangle\n";
}
};

// 使用
int main() {
    Circle circle;
    Rectangle rectangle;
    DrawVisitor drawVisitor;

    circle.accept(&drawVisitor);
    rectangle.accept(&drawVisitor);

    return 0;
}
posted @   35-brother  阅读(15)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示