设计模式总结(四)

上一篇总结了设计模式的结构型, 接下来总结一下设计模式的几种行为型模式。

模板方法模式:

模板方法模式定义了一个算法的骨架,将一些步骤延迟到子类中实现。这样做的目的是使得子类可以在不改变算法结构的情况下重新定义算法的某些步骤,从而实现算法的复用和定制化。

模板方法模式通常包含以下角色:

  1. 抽象类(Abstract Class):定义了一个模板方法,其中包含算法的骨架以及一系列抽象方法,这些抽象方法由子类去实现。

  2. 具体子类(Concrete Class):实现了抽象类中定义的抽象方法,从而完成算法的特定步骤。

下面是一个使用模板方法模式的示例:

#include <iostream>

// 抽象类
class AbstractClass {
public:
    // 模板方法
    void templateMethod() {
        // 调用具体方法
        stepOne();
        stepTwo();
        stepThree();
    }

    // 抽象方法,由子类实现
    virtual void stepOne() = 0;
    virtual void stepTwo() = 0;
    virtual void stepThree() = 0;
};

// 具体子类 A
class ConcreteClassA : public AbstractClass {
public:
    void stepOne() override {
        std::cout << "ConcreteClassA: Step One\n";
    }

    void stepTwo() override {
        std::cout << "ConcreteClassA: Step Two\n";
    }

    void stepThree() override {
        std::cout << "ConcreteClassA: Step Three\n";
    }
};

// 具体子类 B
class ConcreteClassB : public AbstractClass {
public:
    void stepOne() override {
        std::cout << "ConcreteClassB: Step One\n";
    }

    void stepTwo() override {
        std::cout << "ConcreteClassB: Step Two\n";
    }

    void stepThree() override {
        std::cout << "ConcreteClassB: Step Three\n";
    }
};

int main() {
    AbstractClass* objectA = new ConcreteClassA();
    AbstractClass* objectB = new ConcreteClassB();

    // 调用模板方法
    objectA->templateMethod();
    objectB->templateMethod();

    delete objectA;
    delete objectB;

    return 0;
}

在上面的示例中,AbstractClass 是一个抽象类,其中定义了模板方法 templateMethod(),以及三个抽象方法 stepOne()stepTwo()stepThree()ConcreteClassAConcreteClassB 是具体子类,分别实现了这三个抽象方法。

main() 函数中,我们创建了 ConcreteClassAConcreteClassB 的实例,并分别调用它们的 templateMethod() 方法,从而演示了模板方法模式的使用。输出结果会显示具体子类中实现的步骤被正确调用。

观察者模式:

观察者模式义了一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并自动更新。观察者模式也被称为发布-订阅(Publish-Subscribe)模式。

观察者模式通常包含以下角色:

  1. 主题(Subject):也称为被观察者或可观察对象,它维护了一个观察者列表,并提供了添加、删除和通知观察者的方法。

  2. 观察者(Observer):定义了一个更新接口,使得在主题状态变化时能够接收到通知并进行相应的更新操作。

  3. 具体主题(Concrete Subject):是主题的具体实现,负责维护状态并在状态变化时通知观察者。

  4. 具体观察者(Concrete Observer):实现了观察者接口,当接收到主题的通知时进行相应的更新操作。

观察者模式的优点包括降低了主题和观察者之间的耦合度,使得主题和观察者可以独立变化;同时也支持广播通知,多个观察者可以同时监听同一个主题。

下面是一个简单的 C++ 示例,演示了观察者模式的实现:

#include <iostream>
#include <vector>

// 观察者接口
class Observer {
public:
    virtual void update(const std::string& message) = 0;
};

// 具体观察者 A
class ConcreteObserverA : public Observer {
public:
    void update(const std::string& message) override {
        std::cout << "ConcreteObserverA received message: " << message << std::endl;
    }
};

// 具体观察者 B
class ConcreteObserverB : public Observer {
public:
    void update(const std::string& message) override {
        std::cout << "ConcreteObserverB received message: " << message << std::endl;
    }
};

// 主题接口
class Subject {
public:
    virtual void attach(Observer* observer) = 0;
    virtual void detach(Observer* observer) = 0;
    virtual void notify(const std::string& message) = 0;
};

// 具体主题
class ConcreteSubject : public Subject {
private:
    std::vector<Observer*> observers;

public:
    void attach(Observer* observer) override {
        observers.push_back(observer);
    }

    void detach(Observer* observer) override {
        for (auto it = observers.begin(); it != observers.end(); ++it) {
            if (*it == observer) {
                observers.erase(it);
                break;
            }
        }
    }

    void notify(const std::string& message) override {
        for (auto observer : observers) {
            observer->update(message);
        }
    }

    void changeState(const std::string& newState) {
        notify(newState);
    }
};

int main() {
    ConcreteObserverA observerA;
    ConcreteObserverB observerB;

    ConcreteSubject subject;
    subject.attach(&observerA);
    subject.attach(&observerB);

    subject.changeState("New State");

    subject.detach(&observerA);

    subject.changeState("Another State");

    return 0;
}

在上面的示例中,我们定义了观察者模式中的观察者接口 Observer 和主题接口 Subject,并实现了具体的观察者类 ConcreteObserverAConcreteObserverB,以及具体的主题类 ConcreteSubject

main() 函数中,我们创建了两个具体的观察者对象 observerAobserverB,并将它们注册到具体主题对象 subject 中。然后我们调用 subjectchangeState() 方法改变主题的状态,并观察到具体观察者接收到了相应的通知并进行了更新操作。最后我们将 observerA 从主题中解除注册,并再次改变主题的状态,观察到只有 observerB 接收到了通知。

策略模式:

策略模式定义了一系列算法,并将每个算法封装起来,使得它们可以互相替换,使得算法的变化不会影响到使用算法的客户端。策略模式也被称为政策模式。

策略模式通常包含以下角色:

  1. 环境类(Context):维护一个对策略对象的引用,并在需要时调用策略对象的方法。

  2. 策略接口(Strategy Interface):定义了策略族的通用接口,通常包含一个或多个方法用于执行具体的算法。

  3. 具体策略类(Concrete Strategy):实现了策略接口,提供了具体的算法实现。

策略模式的优点包括将算法的实现与使用算法的客户端解耦,使得算法可以独立变化而不影响客户端代码;同时也支持运行时动态地选择和切换算法。

下面是一个简单的 C++ 示例,演示了策略模式的实现:

#include <iostream>

// 策略接口
class Strategy {
public:
    virtual void execute() = 0;
};

// 具体策略类 A
class ConcreteStrategyA : public Strategy {
public:
    void execute() override {
        std::cout << "Executing ConcreteStrategyA\n";
    }
};

// 具体策略类 B
class ConcreteStrategyB : public Strategy {
public:
    void execute() override {
        std::cout << "Executing ConcreteStrategyB\n";
    }
};

// 环境类
class Context {
private:
    Strategy* strategy;

public:
    Context(Strategy* strategy) : strategy(strategy) {}

    void setStrategy(Strategy* strategy) {
        this->strategy = strategy;
    }

    void executeStrategy() {
        if (strategy) {
            strategy->execute();
        } else {
            std::cout << "No strategy set\n";
        }
    }
};

int main() {
    ConcreteStrategyA strategyA;
    ConcreteStrategyB strategyB;

    Context context(&strategyA);
    context.executeStrategy();

    context.setStrategy(&strategyB);
    context.executeStrategy();

    return 0;
}

在上面的示例中,我们定义了策略模式中的策略接口 Strategy,以及具体的策略类 ConcreteStrategyAConcreteStrategyB,它们实现了策略接口中的 execute() 方法。还定义了环境类 Context,它维护了一个对策略对象的引用,并在需要时调用策略对象的 execute() 方法。

main() 函数中,我们创建了具体的策略对象 strategyAstrategyB,然后分别将它们传递给环境类 context,并调用 contextexecuteStrategy() 方法执行相应的策略。输出结果会显示具体的策略类被正确调用。

责任链模式:

责任链模式通过一系列处理器对象(也称为责任链)来处理请求,每个处理器对象都包含了对请求的处理逻辑,并且知道下一个处理器对象是谁。请求会从链的顶部开始沿着链传递,直到有一个处理器对象能够处理该请求为止。

责任链模式的主要目的是解耦发送者和接收者之间的关系,使得多个对象都有机会处理请求,从而避免将请求的发送者与接收者直接耦合在一起。

责任链模式通常包含以下角色:

  1. 抽象处理器(Handler):定义了一个处理请求的接口,并包含了一个指向下一个处理器的引用。

  2. 具体处理器(Concrete Handler):实现了抽象处理器接口,负责处理具体的请求,如果自己无法处理则将请求传递给下一个处理器。

下面是一个简单的 C++ 示例,演示了责任链模式的实现:

#include <iostream>
#include <string>

// 抽象处理器
class Handler {
protected:
    Handler* successor;

public:
    Handler() : successor(nullptr) {}

    void setSuccessor(Handler* successor) {
        this->successor = successor;
    }

    virtual void handleRequest(const std::string& request) = 0;
};

// 具体处理器 A
class ConcreteHandlerA : public Handler {
public:
    void handleRequest(const std::string& request) override {
        if (request == "A") {
            std::cout << "ConcreteHandlerA handles the request\n";
        } else if (successor != nullptr) {
            successor->handleRequest(request);
        }
    }
};

// 具体处理器 B
class ConcreteHandlerB : public Handler {
public:
    void handleRequest(const std::string& request) override {
        if (request == "B") {
            std::cout << "ConcreteHandlerB handles the request\n";
        } else if (successor != nullptr) {
            successor->handleRequest(request);
        }
    }
};

// 具体处理器 C
class ConcreteHandlerC : public Handler {
public:
    void handleRequest(const std::string& request) override {
        if (request == "C") {
            std::cout << "ConcreteHandlerC handles the request\n";
        } else if (successor != nullptr) {
            successor->handleRequest(request);
        }
    }
};

int main() {
    ConcreteHandlerA handlerA;
    ConcreteHandlerB handlerB;
    ConcreteHandlerC handlerC;

    handlerA.setSuccessor(&handlerB);
    handlerB.setSuccessor(&handlerC);

    handlerA.handleRequest("A");
    handlerA.handleRequest("B");
    handlerA.handleRequest("C");
    handlerA.handleRequest("D");

    return 0;
}

在上面的示例中,我们定义了责任链模式中的抽象处理器 Handler 和具体的处理器类 ConcreteHandlerAConcreteHandlerBConcreteHandlerC,它们实现了抽象处理器接口中的 handleRequest() 方法。

main() 函数中,我们创建了具体的处理器对象,并通过 setSuccessor() 方法将它们连接成责任链。然后我们调用 handlerAhandleRequest() 方法,并传递不同的请求,观察输出结果可以看到请求会从链的顶部开始传递,直到找到合适的处理器来处理请求为止。

命令模式:

命令模式将请求封装成一个对象,从而使得可以用不同的请求对客户端参数化,对请求排队或者记录请求日志,以及支持可撤销的操作。

命令模式通常包含以下角色:

  1. 命令接口(Command):定义了执行请求的接口,通常包含一个执行方法(execute)。

  2. 具体命令(Concrete Command):实现了命令接口,负责执行具体的请求操作,并包含了接收者对象的引用。

  3. 调用者(Control):负责调用命令对象执行请求。

下面是一个简单的 C++ 示例,演示了命令模式的实现:

#include <iostream>
#include <vector>

// 定义一个命令接口
class Command {
public:
    virtual void execute() = 0;
};

// 具体命令类
class LightOnCommand : public Command {
public:
    void execute() override {
        std::cout << "Light is on" << std::endl;
    }
};

class LightOffCommand : public Command {
public:
    void execute() override {
        std::cout << "Light is off" << std::endl;
    }
};

// 调用者类
class RemoteControl {
private:
    std::vector<Command*> commands;

public:
    void addCommand(Command* command) {
        commands.push_back(command);
    }

    void pressButton(int index) {
        if (index >= 0 && index < commands.size()) {
            commands[index]->execute();
        }
    }
};

int main() {
    RemoteControl remote;

    // 创建命令
    Command* lightOn = new LightOnCommand();
    Command* lightOff = new LightOffCommand();

    // 添加命令到遥控器
    remote.addCommand(lightOn);
    remote.addCommand(lightOff);

    // 执行命令
    remote.pressButton(0);
    remote.pressButton(1);

    return 0;
}

在这个示例中,我们定义了一个Command接口,然后实现了两个具体的命令类LightOnCommandLightOffCommand。然后我们创建了一个RemoteControl类,它可以添加命令并执行。在main函数中,我们演示了如何使用这个简单的命令模式来控制灯的开关。

状态模式:

状态模式允许一个对象在其内部状态改变时改变其行为。状态模式的关键在于定义了一系列表示不同状态的对象,并将这些状态对象封装成独立的类,使得状态的改变可以通过改变状态对象来实现,从而使得对象的行为在不同状态下有所不同。

状态模式通常包含以下角色:

  1. 环境类(Context):定义了客户端感兴趣的接口,并维护了一个当前状态对象的引用。

  2. 抽象状态类(State):定义了一个接口用于封装与环境对象的一个特定状态相关的行为。

  3. 具体状态类(Concrete State):实现了抽象状态类中定义的接口,负责处理环境对象在当前状态下的行为。

下面是一个简单的 C++ 示例,演示了状态模式的实现:

#include <iostream>
#include <string>

// 环境类
class Context;

// 抽象状态类
class State {
public:
    virtual void handle(Context* context) = 0;
};

// 具体状态类 A
class ConcreteStateA : public State {
public:
    void handle(Context* context) override;
};

// 具体状态类 B
class ConcreteStateB : public State {
public:
    void handle(Context* context) override;
};

// 环境类
class Context {
private:
    State* state;

public:
    Context() : state(nullptr) {}

    void setState(State* newState) {
        state = newState;
    }

    void request() {
        if (state) {
            state->handle(this);
        } else {
            std::cout << "No state set\n";
        }
    }
};

void ConcreteStateA::handle(Context* context) {
    std::cout << "ConcreteStateA handles the request\n";
    context->setState(new ConcreteStateB());  // 切换到具体状态类 B
}

void ConcreteStateB::handle(Context* context) {
    std::cout << "ConcreteStateB handles the request\n";
    context->setState(new ConcreteStateA());  // 切换到具体状态类 A
}

int main() {
    Context context;

    context.request();  // 输出 "No state set"

    context.setState(new ConcreteStateA());
    context.request();  // 输出 "ConcreteStateA handles the request"

    context.request();  // 输出 "ConcreteStateB handles the request"
    
    return 0;
}

在上面的示例中,我们定义了状态模式中的环境类 Context、抽象状态类 State 和具体状态类 ConcreteStateAConcreteStateB

main() 函数中,我们创建了环境对象 context,并设置了初始状态为具体状态类 A。然后我们调用环境对象的 request() 方法,观察输出结果可以看到环境对象根据当前状态的不同而执行了不同的行为,并且可以动态地切换状态。

访问者模式:

访问者模式可以在不修改现有类的前提下,通过为现有类添加新的访问者(Visitor)类来实现对现有类功能的扩展。访问者模式的核心思想是将数据结构与数据操作分离,使得数据结构和数据操作可以独立变化。

访问者模式通常包含以下角色:

  1. 抽象访问者(Visitor):定义了对每个具体元素类的访问行为,通常包含一个访问方法用于接收具体元素类的实例。

  2. 具体访问者(Concrete Visitor):实现了抽象访问者中定义的访问方法,负责实现对具体元素类的不同访问操作。

  3. 抽象元素(Element):定义了一个接受访问者对象的接口,通常包含一个接受方法用于接收访问者对象。

  4. 具体元素(Concrete Element):实现了抽象元素中定义的接受方法,负责接受访问者对象并调用访问者对象的访问方法。

  5. 对象结构(Object Structure):用于存储具体元素对象,并提供接口让访问者访问其中的元素。

下面是一个简单的 C++ 示例,演示了访问者模式的实现:

#include <iostream>
#include <vector>

// 前向声明
class ConcreteElementA;
class ConcreteElementB;

// 抽象访问者
class Visitor {
public:
    virtual void visitConcreteElementA(ConcreteElementA* element) = 0;
    virtual void visitConcreteElementB(ConcreteElementB* element) = 0;
};

// 具体访问者 A
class ConcreteVisitorA : public Visitor {
public:
    void visitConcreteElementA(ConcreteElementA* element) override {
        std::cout << "ConcreteVisitorA visited ConcreteElementA\n";
    }

    void visitConcreteElementB(ConcreteElementB* element) override {
        std::cout << "ConcreteVisitorA visited ConcreteElementB\n";
    }
};

// 具体访问者 B
class ConcreteVisitorB : public Visitor {
public:
    void visitConcreteElementA(ConcreteElementA* element) override {
        std::cout << "ConcreteVisitorB visited ConcreteElementA\n";
    }

    void visitConcreteElementB(ConcreteElementB* element) override {
        std::cout << "ConcreteVisitorB visited ConcreteElementB\n";
    }
};

// 抽象元素
class Element {
public:
    virtual void accept(Visitor* visitor) = 0;
};

// 具体元素 A
class ConcreteElementA : public Element {
public:
    void accept(Visitor* visitor) override {
        visitor->visitConcreteElementA(this);
    }
};

// 具体元素 B
class ConcreteElementB : public Element {
public:
    void accept(Visitor* visitor) override {
        visitor->visitConcreteElementB(this);
    }
};

// 对象结构
class ObjectStructure {
private:
    std::vector<Element*> elements;

public:
    void addElement(Element* element) {
        elements.push_back(element);
    }

    void accept(Visitor* visitor) {
        for (Element* element : elements) {
            element->accept(visitor);
        }
    }
};

int main() {
    ConcreteElementA elementA;
    ConcreteElementB elementB;

    ObjectStructure objectStructure;
    objectStructure.addElement(&elementA);
    objectStructure.addElement(&elementB);

    ConcreteVisitorA visitorA;
    ConcreteVisitorB visitorB;

    objectStructure.accept(&visitorA);
    objectStructure.accept(&visitorB);

    return 0;
}

在上面的示例中,我们定义了访问者模式中的抽象访问者 Visitor 和具体访问者类 ConcreteVisitorAConcreteVisitorB,以及抽象元素类 Element 和具体元素类 ConcreteElementAConcreteElementB

我们还定义了对象结构类 ObjectStructure,用于存储具体元素对象,并提供接口让访问者访问其中的元素。

main() 函数中,我们创建了具体的元素对象 elementAelementB,并添加到对象结构中。然后我们创建了具体的访问者对象 visitorAvisitorB,并通过对象结构的 accept() 方法让访问者访问其中的元素。观察输出结果可以看到不同的访问者对象对不同的元素对象执行了不同的访问操作。

迭代器模式:

迭代器模式提供一种顺序访问集合对象元素的方法,而不暴露集合对象的内部表示。迭代器模式使得可以访问一个聚合对象的元素而无需暴露其内部结构。

迭代器模式通常包含以下角色:

  1. 迭代器接口(Iterator):定义了迭代器的通用操作,例如获取下一个元素、判断是否还有下一个元素等。

  2. 具体迭代器(Concrete Iterator):实现了迭代器接口,负责对具体的集合对象进行迭代操作,并记录迭代的当前位置。

  3. 聚合接口(Aggregate):定义了创建迭代器对象的接口,通常包含一个获取迭代器的方法。

  4. 具体聚合类(Concrete Aggregate):实现了聚合接口,负责创建具体迭代器对象,并提供了一种方法让客户端可以访问集合对象的元素。

下面是一个简单的 C++ 示例,演示了迭代器模式的实现:

#include <iostream>
#include <vector>

// 迭代器接口
template<typename T>
class Iterator {
public:
    virtual bool hasNext() const = 0;
    virtual T next() = 0;
};

// 具体迭代器
template<typename T>
class ConcreteIterator : public Iterator<T> {
private:
    std::vector<T> data;
    size_t position;

public:
    ConcreteIterator(const std::vector<T>& elements) : data(elements), position(0) {}

    bool hasNext() const override {
        return position < data.size();
    }

    T next() override {
        if (hasNext()) {
            return data[position++];
        } else {
            throw std::out_of_range("Iterator has reached the end");
        }
    }
};

// 聚合接口
template<typename T>
class Aggregate {
public:
    virtual Iterator<T>* createIterator() = 0;
};

// 具体聚合类
template<typename T>
class ConcreteAggregate : public Aggregate<T> {
private:
    std::vector<T> elements;

public:
    void addElement(const T& element) {
        elements.push_back(element);
    }

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

int main() {
    ConcreteAggregate<int> aggregate;
    aggregate.addElement(1);
    aggregate.addElement(2);
    aggregate.addElement(3);

    Iterator<int>* iterator = aggregate.createIterator();

    while (iterator->hasNext()) {
        std::cout << iterator->next() << " ";
    }
    std::cout << std::endl;

    delete iterator;

    return 0;
}

在上面的示例中,我们定义了迭代器模式中的迭代器接口 Iterator 和具体迭代器类 ConcreteIterator,以及聚合接口 Aggregate 和具体聚合类 ConcreteAggregate

main() 函数中,我们创建了具体聚合对象 aggregate,并添加了一些元素。然后我们通过聚合对象的 createIterator() 方法创建了迭代器对象 iterator,并使用迭代器对象遍历了集合对象的元素并输出。最后别忘了释放迭代器对象的内存空间,以避免内存泄漏。

备忘录模式:

备忘录模式允许在不破坏封装性的前提下捕获对象的内部状态,并在对象之外保存这个状态,从而在需要时可以将对象恢复到之前的状态。备忘录模式的关键在于将对象的状态保存到一个备忘录对象中,并提供了一种方法来恢复对象的状态。

备忘录模式通常包含以下角色:

  1. 发起人(Originator):负责创建备忘录对象,并可以使用备忘录对象来恢复自身的状态。

  2. 备忘录(Memento):负责存储发起人对象的内部状态,可以包含多个状态属性。

  3. 负责人(Caretaker):负责保存备忘录对象,但不对备忘录对象进行操作,只负责存储和获取备忘录。

下面是一个简单的 C++ 示例,演示了备忘录模式的实现:

#include <iostream>
#include <string>

// 备忘录类
class Memento {
private:
    std::string state;

public:
    Memento(const std::string& s) : state(s) {}

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

// 发起人类
class Originator {
private:
    std::string state;

public:
    void setState(const std::string& s) {
        std::cout << "Setting state to: " << s << std::endl;
        state = s;
    }

    Memento* createMemento() {
        return new Memento(state);
    }

    void restoreFromMemento(const Memento* memento) {
        state = memento->getState();
        std::cout << "Restored state to: " << state << std::endl;
    }
};

// 负责人类
class Caretaker {
private:
    Memento* memento;

public:
    void setMemento(Memento* m) {
        memento = m;
    }

    Memento* getMemento() const {
        return memento;
    }
};

int main() {
    Originator originator;
    Caretaker caretaker;

    originator.setState("State 1");
    caretaker.setMemento(originator.createMemento());

    originator.setState("State 2");
    originator.restoreFromMemento(caretaker.getMemento());

    return 0;
}

在上面的示例中,我们定义了备忘录模式中的备忘录类 Memento、发起人类 Originator 和负责人类 Caretaker

main() 函数中,我们创建了发起人对象 originator 和负责人对象 caretaker。首先我们通过发起人对象的 setState() 方法设置了状态为 "State 1",然后通过负责人对象的 setMemento() 方法保存了当前状态的备忘录。接着我们再次通过发起人对象的 setState() 方法设置了状态为 "State 2",然后通过发起人对象的 restoreFromMemento() 方法将状态恢复到之前保存的备忘录的状态,输出结果显示成功恢复到了之前保存的状态。

中介者模式:

中介者模式允许对象之间通过一个中介者对象进行交互,从而减少对象之间的直接耦合。中介者模式的核心思想是将对象之间的通信和交互行为封装到一个中介者对象中,使得对象之间不需要直接相互引用,而是通过中介者对象来进行通信。

中介者模式通常包含以下角色:

  1. 中介者(Mediator):定义了一个接口用于与各个同事对象进行通信,并维护了对各个同事对象的引用。

  2. 具体中介者(Concrete Mediator):实现了中介者接口,负责实现各个同事对象之间的协调和通信。

  3. 同事类(Colleague):定义了一个接口用于与中介者对象进行通信,并保存了对中介者对象的引用。

  4. 具体同事类(Concrete Colleague):实现了同事接口,负责实现自身的业务逻辑,并通过中介者对象与其他同事对象进行通信。

下面是一个简单的 C++ 示例,演示了中介者模式的实现:

#include <iostream>
#include <string>

// 中介者接口
class Mediator {
public:
    virtual void sendMessage(const std::string& message, class Colleague* colleague) const = 0;
};

// 具体中介者
class ConcreteMediator : public Mediator {
public:
    void sendMessage(const std::string& message, class Colleague* colleague) const override;
};

// 同事类接口
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;
};

// 具体同事类 A
class ConcreteColleagueA : public Colleague {
public:
    ConcreteColleagueA(Mediator* mediator) : Colleague(mediator) {}

    void send(const std::string& message) override {
        mediator->sendMessage(message, this);
    }

    void receive(const std::string& message) override {
        std::cout << "ConcreteColleagueA received message: " << message << std::endl;
    }
};

// 具体同事类 B
class ConcreteColleagueB : public Colleague {
public:
    ConcreteColleagueB(Mediator* mediator) : Colleague(mediator) {}

    void send(const std::string& message) override {
        mediator->sendMessage(message, this);
    }

    void receive(const std::string& message) override {
        std::cout << "ConcreteColleagueB received message: " << message << std::endl;
    }
};

void ConcreteMediator::sendMessage(const std::string& message, Colleague* colleague) const {
    if (colleague == nullptr) {
        std::cout << "Colleague is not registered with the mediator\n";
        return;
    }

    if (dynamic_cast<ConcreteColleagueA*>(colleague) != nullptr) {
        colleague->receive("Message from ConcreteMediator: " + message);
    } else if (dynamic_cast<ConcreteColleagueB*>(colleague) != nullptr) {
        colleague->receive("Message from ConcreteMediator: " + message);
    } else {
        std::cout << "Unknown colleague type\n";
    }
}

int main() {
    ConcreteMediator mediator;

    ConcreteColleagueA colleagueA(&mediator);
    ConcreteColleagueB colleagueB(&mediator);

    colleagueA.send("Hello from Colleague A");
    colleagueB.send("Hi from Colleague B");

    return 0;
}

在上面的示例中,我们定义了中介者模式中的中介者接口 Mediator 和具体中介者类 ConcreteMediator,以及同事类接口 Colleague 和具体同事类 ConcreteColleagueAConcreteColleagueB

main() 函数中,我们创建了具体中介者对象 mediator 和具体同事对象 colleagueAcolleagueB,并通过同事对象的 send() 方法发送消息,中介者对象会根据消息的来源调用对应的同事对象的 receive() 方法来处理消息。输出结果会显示消息被正确地发送和接收。

  • 17
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值