上一篇: 02-结构型设计模式(共7种)
1. Strategy(策略模式)
策略模式是一种行为型设计模式,它定义了一系列算法,将每个算法封装到独立的类中,并使它们可以互相替换。这样可以使算法的变化独立于使用算法的客户端。
在 C++ 中,策略模式通常涉及以下几个角色:
①. Strategy(策略接口):定义了所有支持的算法的通用接口。
②. ConcreteStrategy(具体策略类):实现了策略接口,提供了具体的算法实现。
③. Context(上下文):维护一个对策略对象的引用,并在需要时调用策略对象的方法。
以下是模式示例:
#include <iostream>// 策略接口
class Strategy {
public:virtual void execute() = 0;
};// 具体策略类A
class ConcreteStrategyA : public Strategy {
public:void execute() override {std::cout << "Executing Strategy A" << std::endl;}
};// 具体策略类B
class ConcreteStrategyB : public Strategy {
public:void execute() override {std::cout << "Executing Strategy B" << std::endl;}
};// 上下文类
class Context {
private:Strategy* strategy;public:Context(Strategy* strat) : strategy(strat) {}void setStrategy(Strategy* strat) {strategy = strat;}void executeStrategy() {strategy->execute();}
};int main() {ConcreteStrategyA strategyA;ConcreteStrategyB strategyB;Context context(&strategyA);context.executeStrategy();context.setStrategy(&strategyB);context.executeStrategy();return 0;
}
2. Observer(观察者模式)
观察者模式是一种行为型设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并自动更新。这种模式也被称为:发布-订阅(Publish-Subscribe)模式。
在 C++ 中,观察者模式通常涉及以下几个角色:
①. Subject(主题):定义了一个接口,用于添加、删除和通知观察者对象。
②. ConcreteSubject(具体主题):实现了主题接口,并维护了观察者对象的列表,可以对观察者进行增加、删除和通知操作。
③. Observer(观察者):定义了一个接口,用于接收主题对象的通知。
④. ConcreteObserver(具体观察者):实现了观察者接口,并在接收到通知时执行相应的操作。
以下是模式示例:
#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 << "Concrete Observer A received message: " << message << std::endl;}
};// 具体观察者B
class ConcreteObserverB : public Observer {
public:void update(const std::string& message) override {std::cout << "Concrete Observer B received message: " << message << std::endl;}
};// 主题接口
class Subject {
protected:std::vector<Observer*> observers;public:virtual void attach(Observer* observer) {observers.push_back(observer);}virtual void detach(Observer* observer) {observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());}virtual void notify(const std::string& message) {for (Observer* observer : observers) {observer->update(message);}}
};// 具体主题
class ConcreteSubject : public Subject {
public:void doSomething(const std::string& message) {std::cout << "Subject is doing something..." << std::endl;notify(message);}
};int main() {ConcreteObserverA observerA;ConcreteObserverB observerB;ConcreteSubject subject;subject.attach(&observerA);subject.attach(&observerB);subject.doSomething("Hello observers!");subject.detach(&observerA);subject.doSomething("Hello again, with one less observer!");return 0;
}
3. Template Method(模板方法模式)
模板方法模式是一种行为型设计模式,它定义了一个算法的骨架,将算法的具体步骤延迟到子类中实现。模板方法模式通过把不变行为放在父类中,将可变行为放在子类中,实现了代码复用和灵活性的结合。
在 C++ 中,模板方法模式通常涉及以下几个角色:
①. AbstractClass(抽象类):定义了一个模板方法,其中包含了算法的骨架,该方法可以包含若干抽象方法和具体方法。
②. ConcreteClass(具体类):继承自抽象类,实现了抽象方法,完成算法的具体步骤。
以下是模式示例:
#include <iostream>// 抽象类
class AbstractClass {
public:// 模板方法void templateMethod() {primitiveOperation1();primitiveOperation2();concreteOperation();hook(); // 可选的钩子方法}// 抽象方法1virtual void primitiveOperation1() = 0;// 抽象方法2virtual void primitiveOperation2() = 0;// 具体方法void concreteOperation() {std::cout << "Concrete Operation" << std::endl;}// 钩子方法(可选实现)virtual void hook() {std::cout << "Default Hook Method" << std::endl;}
};// 具体类A
class ConcreteClassA : public AbstractClass {
public:void primitiveOperation1() override {std::cout << "Concrete Class A - Primitive Operation 1" << std::endl;}void primitiveOperation2() override {std::cout << "Concrete Class A - Primitive Operation 2" << std::endl;}void hook() override {std::cout << "Concrete Class A - Custom Hook Method" << std::endl;}
};// 具体类B
class ConcreteClassB : public AbstractClass {
public:void primitiveOperation1() override {std::cout << "Concrete Class B - Primitive Operation 1" << std::endl;}void primitiveOperation2() override {std::cout << "Concrete Class B - Primitive Operation 2" << std::endl;}
};int main() {AbstractClass* objA = new ConcreteClassA();AbstractClass* objB = new ConcreteClassB();objA->templateMethod();std::cout << std::endl;objB->templateMethod();delete objB;delete objA;return 0;
}
4. Command(命令模式)
命令模式是一种行为型设计模式,它将请求封装为一个对象,从而允许用不同的请求来参数化客户端对象,并且能够支持队列、日志和可撤销的操作。命令模式的核心思想是将请求的发送者和接收者解耦,使得请求发送者只需知道如何发送请求,而不需要知道接收者的具体操作。
在 C++ 中,命令模式通常涉及以下几个角色:
①. Command(命令接口):定义了执行请求的接口,通常包含一个执行方法 execute()。
②. ConcreteCommand(具体命令类):实现了命令接口,负责执行具体的操作。
③. Receiver(接收者):负责实际执行命令的对象。
④. Invoker(调用者):持有命令对象,并在需要时调用命令对象的执行方法。
以下是模式示例:
#include <iostream>// 命令接口
class Command {
public:virtual void execute() = 0;
};// 具体命令类A
class ConcreteCommandA : public Command {
private:std::string receiverState; // 接收者状态Receiver* receiver; // 接收者对象public:ConcreteCommandA(Receiver* rec, const std::string& state) : receiver(rec), receiverState(state) {}void execute() override {std::cout << "Concrete Command A executed." << std::endl;receiver->action(receiverState);}
};// 具体命令类B
class ConcreteCommandB : public Command {
private:Receiver* receiver; // 接收者对象public:ConcreteCommandB(Receiver* rec) : receiver(rec) {}void execute() override {std::cout << "Concrete Command B executed." << std::endl;receiver->action("B");}
};// 接收者
class Receiver {
public:void action(const std::string& state) {std::cout << "Receiver performing action with state: " << state << std::endl;}
};// 调用者
class Invoker {
private:Command* command;public:Invoker(Command* cmd) : command(cmd) {}void setCommand(Command* cmd) {command = cmd;}void executeCommand() {command->execute();}
};int main() {Receiver receiver;ConcreteCommandA commandA(&receiver, "A");ConcreteCommandB commandB(&receiver);Invoker invoker(&commandA);invoker.executeCommand();invoker.setCommand(&commandB);invoker.executeCommand();return 0;
}
5. Chain of Responsibility(责任链模式)
责任链模式是一种行为型设计模式,它允许将请求沿着处理链传递,并且在链上的每个处理者都有机会处理请求或将其传递给下一个处理者。这种模式可以避免请求发送者和接收者之间的直接耦合,并支持动态添加或修改处理者。
在 C++ 中,责任链模式通常涉及以下几个角色:
①. Handler(处理者接口):定义了处理请求的接口,并包含一个对下一个处理者的引用。
②. ConcreteHandler(具体处理者类):实现了处理者接口,并对请求进行具体处理或将请求传递给下一个处理者。
以下是模式示例:
#include <iostream>// 处理者接口
class Handler {
protected:Handler* nextHandler;public:Handler() : nextHandler(nullptr) {}void setNextHandler(Handler* handler) {nextHandler = handler;}virtual void handleRequest(int request) = 0;
};// 具体处理者A
class ConcreteHandlerA : public Handler {
public:void handleRequest(int request) override {if (request >= 0 && request < 10) {std::cout << "Concrete Handler A handles the request." << std::endl;} else if (nextHandler != nullptr) {nextHandler->handleRequest(request);}}
};// 具体处理者B
class ConcreteHandlerB : public Handler {
public:void handleRequest(int request) override {if (request >= 10 && request < 20) {std::cout << "Concrete Handler B handles the request." << std::endl;} else if (nextHandler != nullptr) {nextHandler->handleRequest(request);}}
};// 客户端
int main() {ConcreteHandlerA handlerA;ConcreteHandlerB handlerB;handlerA.setNextHandler(&handlerB);handlerA.handleRequest(5);handlerA.handleRequest(15);handlerA.handleRequest(25);return 0;
}
6. State(状态模式)
状态模式是一种行为型设计模式,它允许对象在其内部状态发生改变时改变其行为,使得对象看起来好像修改了其类。状态模式将对象的行为封装在不同的状态类中,并将状态的改变委托给当前状态对象,从而实现了状态之间的切换和行为的动态变化。
在 C++ 中,状态模式通常涉及以下几个角色:
①. State(状态接口):定义了一个接口,用于封装与特定状态相关的行为。
②. ConcreteState(具体状态类):实现了状态接口,并实现了与特定状态相关的行为。
③. Context(上下文类):维护一个对当前状态对象的引用,并将状态的改变委托给当前状态对象。
以下是模式示例:
#include <iostream>// 状态接口
class State {
public:virtual void handle() = 0;
};// 具体状态类A
class ConcreteStateA : public State {
public:void handle() override {std::cout << "Concrete State A handled." << std::endl;}
};// 具体状态类B
class ConcreteStateB : public State {
public:void handle() override {std::cout << "Concrete State B handled." << std::endl;}
};// 上下文类
class Context {
private:State* currentState;public:Context(State* initState) : currentState(initState) {}void setState(State* newState) {currentState = newState;}void request() {currentState->handle();}
};int main() {ConcreteStateA stateA;ConcreteStateB stateB;Context context(&stateA);context.request();context.setState(&stateB);context.request();return 0;
}
7. Visitor(访问者模式)
访问者模式是一种行为型设计模式,它能够在不改变元素类(数据结构)本身的前提下,定义作用于这些元素对象的新操作。访问者模式将数据结构与作用于数据结构上的操作解耦,使得操作可以独立变化,同时也增加了新操作的扩展性。
在 C++ 中,访问者模式通常涉及以下几个角色:
①. Visitor(访问者接口):定义了对各种元素对象的访问操作。
②. ConcreteVisitor(具体访问者类):实现了访问者接口,对每种元素对象的访问操作进行具体实现。
③. Element(元素接口):定义了接受访问者对象访问的方法。
④. ConcreteElement(具体元素类):实现了元素接口,并实现了接受访问者对象访问的方法。
⑤. ObjectStructure(对象结构):维护了一个元素对象的集合,并提供了遍历集合并接受访问者对象访问的方法。
以下是模式示例:
#include <iostream>
#include <vector>// 前置声明
class ConcreteVisitor;// 元素接口
class Element {
public:virtual void accept(ConcreteVisitor& visitor) = 0;
};// 具体元素类A
class ConcreteElementA : public Element {
public:void accept(ConcreteVisitor& visitor) override;std::string operationA() const;
};// 具体元素类B
class ConcreteElementB : public Element {
public:void accept(ConcreteVisitor& visitor) override;int operationB() const;
};// 访问者接口
class Visitor {
public:// 定义了对各种元素对象的访问操作virtual void visit(ConcreteElementA& element) = 0;virtual void visit(ConcreteElementB& element) = 0;
};// 具体访问者类
class ConcreteVisitor : public Visitor {
public:void visit(ConcreteElementA& element) override {std::cout << "Concrete Visitor visits " << element.operationA() << std::endl;}void visit(ConcreteElementB& element) override {std::cout << "Concrete Visitor visits " << element.operationB() << std::endl;}
};// 具体元素A的接受访问者方法实现
void ConcreteElementA::accept(ConcreteVisitor& visitor) {visitor.visit(*this);
}// 具体元素A的操作
std::string ConcreteElementA::operationA() const {return "Element A";
}// 具体元素B的接受访问者方法实现
void ConcreteElementB::accept(ConcreteVisitor& visitor) {visitor.visit(*this);
}// 具体元素B的操作
int ConcreteElementB::operationB() const {return 123;
}// 对象结构类
class ObjectStructure {
private:std::vector<Element*> elements;public:void addElement(Element* element) {elements.push_back(element);}void accept(ConcreteVisitor& visitor) {for (Element* element : elements) {element->accept(visitor);}}
};int main() {ConcreteElementA elementA;ConcreteElementB elementB;ObjectStructure structure;structure.addElement(&elementA);structure.addElement(&elementB);ConcreteVisitor visitor;structure.accept(visitor);return 0;
}
8. Memento(备忘录模式)
备忘录模式是一种行为型设计模式,它允许在不破坏封装性的前提下捕获对象的内部状态,并在对象之外保存这个状态。备忘录模式通常用于需要记录和恢复对象状态的场景,比如撤销操作。
在 C++ 中,备忘录模式通常涉及以下几个角色:
①. Originator(原发器):负责创建备忘录对象,并在需要时恢复对象状态。
②. Memento(备忘录):用于存储原发器对象的内部状态,可以包含多个状态属性。
③. Caretaker(负责人):负责保存备忘录对象,但不应该修改备忘录对象的状态。
以下是模式示例:
#include <iostream>
#include <string>// 备忘录类
class Memento {
private:std::string state;public:Memento(const std::string& s) : state(s) {}std::string getState() const {return state;}
};// 原发器类
class Originator {
private:std::string state;public:void setState(const std::string& s) {state = s;}std::string getState() const {return state;}Memento createMemento() const {return Memento(state);}void restoreMemento(const Memento& m) {state = m.getState();}
};// 负责人类
class Caretaker {
private:Memento memento;public:void setMemento(const Memento& m) {memento = m;}Memento getMemento() const {return memento;}
};int main() {Originator originator;Caretaker caretaker;// 设置原发器状态originator.setState("State 1");std::cout << "Current State: " << originator.getState() << std::endl;// 创建备忘录并保存caretaker.setMemento(originator.createMemento());// 修改原发器状态originator.setState("State 2");std::cout << "Modified State: " << originator.getState() << std::endl;// 恢复备忘录状态originator.restoreMemento(caretaker.getMemento());std::cout << "Restored State: " << originator.getState() << std::endl;return 0;
}
9. Mediator(中介者模式)
中介者模式是一种行为型设计模式,它通过引入一个中介者对象来减少多个对象之间的直接通信,并且使得这些对象不需要显式地相互引用,从而降低了对象之间的耦合度。中介者模式通常用于处理多个对象之间的复杂交互关系,将这些关系集中管理,使得系统更易于维护和扩展。
在 C++ 中,中介者模式通常涉及以下几个角色:
①. Mediator(中介者接口):定义了各个同事对象之间通信的接口。
②. ConcreteMediator(具体中介者类):实现了中介者接口,并负责协调各个同事对象之间的通信。
③. Colleague(同事类):定义了抽象同事类的接口,每个同事对象都应该持有一个对中介者对象的引用。
④. ConcreteColleague(具体同事类):实现了同事类接口,并在需要时与中介者对象进行通信。
以下是模式示例:
#include <iostream>
#include <string>// 前置声明
class Colleague;// 中介者接口
class Mediator {
public:virtual void sendMessage(const std::string& message, Colleague* colleague) = 0;
};// 具体中介者类
class ConcreteMediator : public Mediator {
private:Colleague* colleagueA;Colleague* colleagueB;public:void setColleagueA(Colleague* colleague) {colleagueA = colleague;}void setColleagueB(Colleague* colleague) {colleagueB = colleague;}void sendMessage(const std::string& message, Colleague* colleague) override {if (colleague == colleagueA) {colleagueB->receiveMessage(message);} else if (colleague == colleagueB) {colleagueA->receiveMessage(message);}}
};// 同事类接口
class Colleague {
protected:Mediator* mediator;public:Colleague(Mediator* med) : mediator(med) {}virtual void sendMessage(const std::string& message) = 0;virtual void receiveMessage(const std::string& message) = 0;
};// 具体同事类A
class ConcreteColleagueA : public Colleague {
public:ConcreteColleagueA(Mediator* med) : Colleague(med) {}void sendMessage(const std::string& message) override {mediator->sendMessage(message, this);}void receiveMessage(const std::string& message) override {std::cout << "Concrete Colleague A received message: " << message << std::endl;}
};// 具体同事类B
class ConcreteColleagueB : public Colleague {
public:ConcreteColleagueB(Mediator* med) : Colleague(med) {}void sendMessage(const std::string& message) override {mediator->sendMessage(message, this);}void receiveMessage(const std::string& message) override {std::cout << "Concrete Colleague B received message: " << message << std::endl;}
};int main() {ConcreteMediator mediator;ConcreteColleagueA colleagueA(&mediator);ConcreteColleagueB colleagueB(&mediator);mediator.setColleagueA(&colleagueA);mediator.setColleagueB(&colleagueB);colleagueA.sendMessage("Hello from Colleague A");colleagueB.sendMessage("Hello from Colleague B");return 0;
}
10. Interpreter(解释器模式)
解释器模式是一种行为型设计模式,它用于定义一个语言的文法,并提供一种解释器来解释该语言中的句子。解释器模式通常用于处理复杂的语法或规则,将这些语法或规则表示为一个抽象语法树,并通过解释器来执行对应的操作。
在 C++ 中,解释器模式通常涉及以下几个角色:
①. AbstractExpression(抽象表达式):定义了一个抽象的解释操作,通常包含一个解释方法 interpret()。
②. TerminalExpression(终结符表达式):实现了抽象表达式接口,并负责解释语言中的终结符。
③. NonterminalExpression(非终结符表达式):实现了抽象表达式接口,并负责解释语言中的非终结符,通常是一个复合表达式。
④. Context(环境类):包含解释器需要的全局信息,通常由解释器来操作。
以下是模式示例:
#include <iostream>
#include <string>
#include <unordered_map>// 环境类
class Context {
private:std::unordered_map<std::string, int> variables;public:void setVariable(const std::string& var, int value) {variables[var] = value;}int getVariable(const std::string& var) const {if (variables.find(var) != variables.end()) {return variables.at(var);}return 0; // 默认返回0}
};// 抽象表达式类
class AbstractExpression {
public:virtual int interpret(Context& context) = 0;
};// 终结符表达式类
class TerminalExpression : public AbstractExpression {
private:std::string variable;public:TerminalExpression(const std::string& var) : variable(var) {}int interpret(Context& context) override {return context.getVariable(variable);}
};// 非终结符表达式类
class NonterminalExpression : public AbstractExpression {
private:AbstractExpression* expressionA;AbstractExpression* expressionB;public:NonterminalExpression(AbstractExpression* expA, AbstractExpression* expB): expressionA(expA), expressionB(expB) {}int interpret(Context& context) override {return expressionA->interpret(context) + expressionB->interpret(context);}
};int main() {Context context;context.setVariable("a", 5);context.setVariable("b", 10);AbstractExpression* expression = new NonterminalExpression(new TerminalExpression("a"), new TerminalExpression("b"));int result = expression->interpret(context);std::cout << "Result: " << result << std::endl;delete expression;return 0;
}