CppStack

C++技术栈一站式学习 · ‌业精于勤,荒于嬉;行成于思,毁于随。

C++ 设计模式详解(三):行为型模式

Tags = [ C++Pattern ]

行为型模式(Behavioral Patterns)关注 对象之间的职责分配与交互方式,帮助系统更灵活地应对需求变化。
常见的行为型模式包括:

  1. 观察者(Observer)
  2. 策略(Strategy)
  3. 命令(Command)
  4. 责任链(Chain of Responsibility)
  5. 状态(State)
  6. 迭代器(Iterator)
  7. 备忘录(Memento)
  8. 模板方法(Template Method)
  9. 访问者(Visitor)
  10. 中介者(Mediator)
  11. 解释器(Interpreter)

行为型模式详解


1. 观察者模式(Observer)

定义:对象间一对多依赖,当一个对象状态改变时,所有依赖它的对象都会收到通知。
场景

  • GUI 事件系统。
  • 发布-订阅模型。
#include <iostream>
#include <vector>
#include <memory>

class Observer {
public:
    virtual void update(int v) = 0;
    virtual ~Observer() = default;
};

class Subject {
    std::vector<Observer*> obs;
    int state{};
public:
    void attach(Observer* o){ obs.push_back(o); }
    void setState(int s){
        state=s;
        for(auto o:obs) o->update(state);
    }
};

class ConcreteObserver : public Observer {
    std::string name;
public:
    ConcreteObserver(std::string n):name(n){}
    void update(int v) override { std::cout << name << " got " << v << "\n"; }
};

int main() {
    Subject s;
    ConcreteObserver a("A"), b("B");
    s.attach(&a); s.attach(&b);
    s.setState(42);
}

2. 策略模式(Strategy)

定义:定义一系列算法,将它们封装起来,使它们可以互换。
场景

  • 排序算法选择。
  • 支付方式选择。
#include <iostream>
#include <memory>

class Strategy {
public:
    virtual void execute() = 0;
    virtual ~Strategy() = default;
};

class StrategyA : public Strategy {
public:
    void execute() override { std::cout << "Algorithm A\n"; }
};

class StrategyB : public Strategy {
public:
    void execute() override { std::cout << "Algorithm B\n"; }
};

class Context {
    std::unique_ptr<Strategy> strat;
public:
    Context(std::unique_ptr<Strategy> s):strat(std::move(s)){}
    void run(){ strat->execute(); }
};

int main() {
    Context c(std::make_unique<StrategyA>());
    c.run();
}

3. 命令模式(Command)

定义:将请求封装为对象,从而可用不同请求、队列或日志来参数化对象。
场景

  • 撤销/重做。
  • 任务队列。
#include <iostream>
#include <vector>
#include <memory>

class Command {
public:
    virtual void execute() = 0;
    virtual ~Command() = default;
};

class Receiver {
public:
    void action(){ std::cout << "Receiver action\n"; }
};

class ConcreteCommand : public Command {
    Receiver* r;
public:
    ConcreteCommand(Receiver* rr):r(rr){}
    void execute() override { r->action(); }
};

class Invoker {
    std::vector<std::unique_ptr<Command>> cmds;
public:
    void add(std::unique_ptr<Command> c){ cmds.push_back(std::move(c)); }
    void run(){ for(auto& c:cmds) c->execute(); }
};

int main() {
    Receiver r;
    Invoker i;
    i.add(std::make_unique<ConcreteCommand>(&r));
    i.run();
}

4. 责任链模式(Chain of Responsibility)

定义:将请求沿着处理链传递,直到有对象处理它为止。
场景

  • 日志系统(不同级别处理)。
  • 事件冒泡。
#include <iostream>
#include <memory>

class Handler {
protected:
    std::shared_ptr<Handler> next;
public:
    void setNext(std::shared_ptr<Handler> n){ next=n; }
    virtual void handle(int v){
        if(next) next->handle(v);
    }
    virtual ~Handler()=default;
};

class ConcreteHandlerA : public Handler {
public:
    void handle(int v) override {
        if(v<10) std::cout << "A handled " << v << "\n";
        else Handler::handle(v);
    }
};

class ConcreteHandlerB : public Handler {
public:
    void handle(int v) override {
        if(v>=10) std::cout << "B handled " << v << "\n";
        else Handler::handle(v);
    }
};

int main() {
    auto a=std::make_shared<ConcreteHandlerA>();
    auto b=std::make_shared<ConcreteHandlerB>();
    a->setNext(b);
    a->handle(5);
    a->handle(20);
}

5. 状态模式(State)

定义:允许对象在内部状态改变时改变其行为,看起来像是修改了类。
场景

  • 游戏角色状态(行走、跳跃、攻击)。
  • TCP 连接状态。
#include <iostream>
#include <memory>

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

class Context {
    std::unique_ptr<State> state;
public:
    void setState(std::unique_ptr<State> s){ state=std::move(s); }
    void request(){ state->handle(); }
};

class StateA : public State {
public:
    void handle() override { std::cout << "State A\n"; }
};

class StateB : public State {
public:
    void handle() override { std::cout << "State B\n"; }
};

int main() {
    Context c;
    c.setState(std::make_unique<StateA>());
    c.request();
    c.setState(std::make_unique<StateB>());
    c.request();
}

6. 迭代器模式(Iterator)

定义:提供一种方法顺序访问聚合对象的元素,而不暴露其内部表示。
场景

  • 容器遍历。
  • 自定义集合。
#include <iostream>
#include <vector>

class Iterator {
    std::vector<int>& data;
    size_t idx=0;
public:
    Iterator(std::vector<int>& d):data(d){}
    bool hasNext(){ return idx<data.size(); }
    int next(){ return data[idx++]; }
};

int main() {
    std::vector<int> v={1,2,3};
    Iterator it(v);
    while(it.hasNext()) std::cout << it.next() << " ";
}

7. 备忘录模式(Memento)

定义:在不破坏封装的前提下,捕获对象的内部状态,并在对象之外保存。
场景

  • 撤销功能。
  • 游戏存档。
#include <iostream>
#include <string>

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

class Originator {
    std::string state;
public:
    void setState(std::string s){ state=s; }
    std::string getState(){ return state; }
    Memento save(){ return Memento(state); }
    void restore(const Memento& m){ state=m.getState(); }
};

int main() {
    Originator o;
    o.setState("A");
    auto m=o.save();
    o.setState("B");
    o.restore(m);
    std::cout << o.getState(); // A
}

8. 模板方法模式(Template Method)

定义:在父类中定义算法骨架,将某些步骤延迟到子类实现。
场景

  • 框架方法调用。
  • 数据处理流程。
#include <iostream>

class AbstractClass {
public:
    void templateMethod(){
        step1();
        step2();
    }
    virtual void step1()=0;
    virtual void step2()=0;
};

class ConcreteClass : public AbstractClass {
public:
    void step1() override { std::cout << "Step1\n"; }
    void step2() override { std::cout << "Step2\n"; }
};

int main() {
    ConcreteClass c;
    c.templateMethod();
}

9. 访问者模式(Visitor)

定义:将操作与对象结构分离,使得在不修改类的情况下增加新操作。
场景

  • 编译器 AST 遍历。
  • 对象结构的多种操作。
#include <iostream>
#include <vector>
#include <memory>

class Visitor;

class Element {
public:
    virtual void accept(Visitor& v)=0;
    virtual ~Element()=default;
};

class ConcreteElementA;
class ConcreteElementB;

class Visitor {
public:
    virtual void visit(ConcreteElementA&)=0;
    virtual void visit(ConcreteElementB&)=0;
};

class ConcreteElementA : public Element {
public:
    void accept(Visitor& v) override { v.visit(*this); }
};

class ConcreteElementB : public Element {
public:
    void accept(Visitor& v) override { v.visit(*this); }
};

class ConcreteVisitor : public Visitor {
public:
    void visit(ConcreteElementA&) override { std::cout << "Visit A\n"; }
    void visit(ConcreteElementB&) override { std::cout << "Visit B\n"; }
};

int main() {
    std::vector<std::unique_ptr<Element>> elems;
    elems.push_back(std::make_unique<ConcreteElementA>());
    elems.push_back(std::make_unique<ConcreteElementB>());
    ConcreteVisitor v;
    for(auto& e:elems) e->accept(v);
}

10. 中介者模式(Mediator)

定义:用一个中介对象封装一系列对象的交互,使对象不需要显式引用彼此。
场景

  • 聊天室。
  • GUI 控件交互。
#include <iostream>
#include <string>
#include <vector>

class Mediator;

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

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

class ConcreteColleague : public Colleague {
    std::string name;
public:
    ConcreteColleague(std::string n,Mediator* m):Colleague(m),name(n){}
    void send(const std::string& msg) override;
    void receive(const std::string& msg) override { std::cout << name<<" got: "<<msg<<"\n"; }
};

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

void ConcreteColleague::send(const std::string& msg){
    mediator->send(msg,this);
}

int main() {
    ConcreteMediator m;
    ConcreteColleague a("A",&m), b("B",&m);
    m.add(&a); m.add(&b);
    a.send("Hello");
}

11. 解释器模式(Interpreter)

定义:为语言定义文法,并建立解释器来解释句子。
场景

  • 简单脚本语言。
  • 正则表达式解析。
#include <iostream>
#include <string>
#include <memory>

class Context {
public:
    std::string input;
    Context(std::string s):input(s){}
};

class Expression {
public:
    virtual bool interpret(Context& c)=0;
    virtual ~Expression()=default;
};

class TerminalExpression : public Expression {
    std::string data;
public:
    TerminalExpression(std::string d):data(d){}
    bool interpret(Context& c) override {
        return c.input.find(data)!=std::string::npos;
    }
};

class OrExpression : public Expression {
    std::unique_ptr<Expression> e1,e2;
public:
    OrExpression(std::unique_ptr<Expression> a,std::unique_ptr<Expression> b)
        :e1(std::move(a)),e2(std::move(b)){}
    bool interpret(Context& c) override {
        return e1->interpret(c)||e2->interpret(c);
    }
};

int main() {
    Context c("hello world");
    auto expr = std::make_unique<OrExpression>(
        std::make_unique<TerminalExpression>("hello"),
        std::make_unique<TerminalExpression>("bye"));
    std::cout << expr->interpret(c); // 1
}

总结

  • 观察者:一对多通知。
  • 策略:算法可互换。
  • 命令:请求封装。
  • 责任链:请求传递。
  • 状态:状态驱动行为。
  • 迭代器:顺序访问。
  • 备忘录:保存恢复状态。
  • 模板方法:算法骨架。
  • 访问者:操作与结构分离。
  • 中介者:集中管理交互。
  • 解释器:定义语言解释。

行为型模式的核心是 解耦对象之间的交互,提升系统的灵活性和可扩展性