《C++设计模式》——行为型

前言

行为型模式是对在不同的对象之间划分责任和算法的抽象化。行为型模式不仅仅关注类和对象的结构,而且重点关注它们之间的相互作用。

Interpreter(解释器)

Template Method(模板方法)

Chain of Responsibility(责任链)

Command(命令)

Iterator(迭代器)

Mediator(中介者)

Memento(备忘录)

Observer(观察者)

GOOD:定义了一种一对多的关系,让多个观察对象(公司员工)同时监听一个主题对象(秘书),主题对象状态发生变化时,会通知所有的观察者,使它们能够更新自己。
在这里插入图片描述
observer.h

#ifndef OBSERVER_H
#define OBSERVER_H

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

using namespace std;

class SecretaryBase;

// 抽象观察者
class CObserverBase {
protected:
    string name;
    SecretaryBase *sub;
public:
    CObserverBase(string strname, SecretaryBase *strsub) {
        name = strname;
        sub = strsub;
    }

    virtual void Update() = 0;
};

// 具体的观察者,看股票的
class StockObserver : public CObserverBase {
public:
    StockObserver(string strname, SecretaryBase *strsub) : CObserverBase(strname, strsub) {

    }

    virtual void Update();
};

// 具体的观察者,看NBA的
class NBAObserver : public CObserverBase {
public:
    NBAObserver(string strname, SecretaryBase *strsub) : CObserverBase(strname, strsub) {}

    virtual void Update();
};

// 抽象通知者
class SecretaryBase {
public:
    string action;
    vector<CObserverBase *> observers;
public:
    virtual void Attach(CObserverBase *observer) = 0;

    virtual void Notify() = 0;
};

// 具体通知者
class Secretary : public SecretaryBase {
public:
    void Attach(CObserverBase *ob) {
        observers.emplace_back(ob);
    }

    void Notify() {
        for (CObserverBase *observer: observers) {
            observer->Update();
        }
    }
};

void StockObserver::Update() {
    cout << name << ":" << sub->action << ",不要玩股票了,要开始工作了" << endl;
}

void NBAObserver::Update() {
    cout << name << ":" << sub->action << ",不要看NBA了,老板来了" << endl;
}


#endif //OBSERVER_H

main.cpp

#include "observer.h"

using namespace std;

int main() {
    system("chcp 65001");
    // 观察者模式
    SecretaryBase *p = new Secretary(); // 创建观察者

    // 被观察者的对象
    CObserverBase *s1 = new NBAObserver("小李", p);
    CObserverBase *s2 = new StockObserver("小赵", p);
    // 加入观察队列
    p->Attach(s1);
    p->Attach(s2);
    // 事件
    p->action = "老板来了";
    // 通知
    p->Notify();

    return 0;
}

输出:

State=On 
State=Off
State=On

State(状态)

GOOD:当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,可考虑用到状态模式。
在这里插入图片描述
state.h

#ifndef STATE_H
#define STATE_H

#include<iostream>

using namespace std;

class State;
class ForenoonState;
class NoonState;
class AfternonnState;
class EveningState;
class SleepingState;
class RestState;
class Work;

// 抽象状态角色,负责定义各个状态有哪些行为,该抽象状态包含所有具体状态的方法。并且封装环境角色,帮助切换状态。
class State {
public:
    virtual ~State() = default;

    virtual void writeprogram(Work *w) = 0;
};

// Context 角色,在该类内部维护一个ConcreteState子类的一个实例,可以负责具体状态的切换
// 工作
class Work {
private:
    State *current;
    double m_hour;
    bool m_finish;
public:
    Work();

    ~Work();

    void setHour(double hour) { m_hour = hour; }

    double getHour() const { return m_hour; }

    void setFinish(bool finish) { m_finish = finish; }

    bool getFinish() const { return m_finish; }

    void SetState(State *s) {
        delete current;
        current = s;
    }

    void WorkProgram() {
        current->writeprogram(this);
    }
};

// 下面都是具体的状态类,每一个具体状态类必须完成两个职责:该类本状态下要做的事情,以及如何执行到其他具体状态类的状态。
// 上午工作状态
class ForenoonState : public State {
public:
    void writeprogram(Work *w) final;
};

// 中午工作状态
class NoonState : public State {
public:
    void writeprogram(Work *w) final;
};

// 下午工作状态
class AfternoonState : public State {
public:
    void writeprogram(Work *w) final;
};

// 晚些工作状态
class EveningState : public State {
public:
    void writeprogram(Work *w) final;
};

// 睡眠状态
class SleepingState : public State {
public:
    void writeprogram(Work *w) final;

};

//下午休息状态
class RestState : public State {// 下班休息状态
public:
    void writeprogram(Work *w) final;

};

Work::Work() {
    current = new ForenoonState();
}

Work::~Work() {
    delete current;
}

void ForenoonState::writeprogram(Work *w) {
    if (w->getHour() < 12) {
        cout << "当前时间:" << w->getHour() << "点,上午工作,精神百倍" << endl;
    } else {
        w->SetState(new NoonState());
        w->WorkProgram();
    }
}

void NoonState::writeprogram(Work *w) {
    if (w->getHour() < 13) {
        cout << "当前时间:" << w->getHour() << "点,吃午饭,睡午觉" << endl;
    } else {
        w->SetState(new AfternoonState());
        w->WorkProgram();
    }
}

void AfternoonState::writeprogram(Work *w) {
    if (w->getHour() < 17) {
        cout << "当前时间:" << w->getHour() << "点,下午状态还不错" << endl;
    } else {
        w->SetState(new EveningState());
        w->WorkProgram();
    }
}

void EveningState::writeprogram(Work *w) {
    if (w->getFinish()) {
        w->SetState(new RestState());
        w->WorkProgram();
    } else {
        if (w->getHour() < 21) {
            cout << "当前时间:" << w->getHour() << "点,加班哦,疲惫至极 " << endl;
        } else {
            w->SetState(new SleepingState());
            w->WorkProgram();
        }
    }
}

void SleepingState::writeprogram(Work *w) {
    cout << "当前时间:" << w->getHour() << "点,不行了,睡着了 " << endl;
}

void RestState::writeprogram(Work *w) {
    cout << "当前时间:" << w->getHour() << "点,下班回家了 " << endl;
}

#endif //STATE_H

main.cpp

#include <iostream>
#include "state.h"

using namespace std;

int main()
{
    system("chcp 65001");
    // 紧急项目
    Work emergencyProjects;

    emergencyProjects.setHour(9);
    emergencyProjects.WorkProgram();

    emergencyProjects.setHour(10);
    emergencyProjects.WorkProgram();

    emergencyProjects.setHour(12);
    emergencyProjects.WorkProgram();

    emergencyProjects.setHour(13);
    emergencyProjects.WorkProgram();

    emergencyProjects.setHour(14);
    emergencyProjects.WorkProgram();

    emergencyProjects.setHour(17);
    emergencyProjects.WorkProgram();

    emergencyProjects.setFinish(false);

    emergencyProjects.setHour(19);
    emergencyProjects.WorkProgram();

    emergencyProjects.setHour(22);
    emergencyProjects.WorkProgram();

    system("pause");
    return 0;
}

Strategy(策略)

定义算法家族,分别封装起来,让它们之间可以互相替换,让算法变化,不会影响到用户
GOOD:适合类中的成员以方法为主,算法经常变动;简化了单元测试(因为每个算法都有自己的类,可以通过自己的接口单独测试。
策略模式和简单工厂基本相同,但简单工厂模式只能解决对象创建问题,对于经常变动的算法(方法)应使用策略模式。
BUG:客户端要做出判断。
在这里插入图片描述

strategy.h

#ifndef STRATEGY_H
#define STRATEGY_H

// 策略基类
class COperation {
public:
    int m_nFirst;
    int m_nSecond;

    virtual double GetResult() {
        double dResult = 0;
        return dResult;
    }
};

// 策略具体类——加法类
class AddOperation : public COperation {
public:
    AddOperation() {

    }
    AddOperation(int a, int b) {
        m_nFirst = a;
        m_nSecond = b;
    }

    double GetResult() final {
        return m_nFirst + m_nSecond;
    }
};

class Context {
private:
    COperation *op;
public:
    Context(COperation *temp) {
        op = temp;
    }

    double GetResult() {
        return op->GetResult();
    }
};

#endif //STRATEGY_H

main.h

#include <iostream>
#include "strategy.h"

using namespace std;

int main() {
    system("chcp 65001");
    // 简单工厂模式
    int a = 1;
    int b = 2;
    // 策略模式
    char c = '+';
    switch (c) {
        case '+':
            Context* context = new Context(new AddOperation(a,b));
            cout<<context->GetResult()<<endl;
            break;
        default:
        break;
    }
    return 0;
}

策略模式与工厂结合

将实例化具体的类过程移至到Context对象的引用中。
strategy.h

  // 策略与工厂结合
  Context(char cType) {
      switch(cType) {
          case '+': op = new AddOperation(3,8);
              break;
          default:
              op = new AddOperation();
              break;
      }
  }

main.h

int main()
{
	int a,b;
	cin>>a>>b;
	Context *test=new Context('+');
	cout<<test­>GetResult()<<endl;
	return 0;
}

Visitor(访问者)

后记

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值