前言
行为型模式是对在不同的对象之间划分责任和算法的抽象化。行为型模式不仅仅关注类和对象的结构,而且重点关注它们之间的相互作用。
Interpreter(解释器)
Template Method(模板方法)
GOOD:把不变的代码部分都转移到父类中,将可变的代码用 virtual 留到子类重写。
template.h
#ifndef CLION_TEST_TEMPLATE_H
#define CLION_TEST_TEMPLATE_H
#include <iostream>
using namespace std;
// 金庸小说考题试卷
class TestPaper {
public:
void TestQuestion1() {
cout << "杨过得到,后来给了郭静,炼成倚天剑、屠龙刀的玄铁可能是[] a.球磨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维"
<< endl;
cout << "答案:" << Answer1() << endl;
}
void TestQuestion2() {
cout << "杨过、程英、陆无双铲除了情花,造成[] a.使这种植物不再害人 b.使一种珍稀物种灭绝 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化"
<< endl;
cout << "答案:" << Answer2() << endl;
}
void TestQuestion3() {
cout << "蓝凤凰致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全部对"
<< endl;
cout << "答案:" << Answer3() << endl;
}
protected:
virtual char Answer1() = 0;
virtual char Answer2() = 0;
virtual char Answer3() = 0;
};
class TestPaperA : public TestPaper {
char Answer1() final {
return 'b';
}
char Answer2() final {
return 'c';
}
char Answer3() final {
return 'a';
}
};
class TestPaperB : public TestPaper {
char Answer1() final {
return 'c';
}
char Answer2() final {
return 'a';
}
char Answer3() final {
return 'a';
}
};
#endif //CLION_TEST_TEMPLATE_H
main.cpp
#include "template.h"
using namespace std;
int main() {
system("chcp 65001");
// 模板方法
cout<<"学生甲抄的试卷:"<<endl;
TestPaper* studentA = new TestPaperA();
studentA->TestQuestion1();
studentA->TestQuestion2();
studentA->TestQuestion3();
cout<<"学生乙抄的试卷:"<<endl;
TestPaper* studentB = new TestPaperB();
studentB->TestQuestion1();
studentB->TestQuestion2();
studentB->TestQuestion3();
return 0;
}
Chain of Responsibility(责任链)
Command(命令)
Iterator(迭代器)
Mediator(中介者)
Memento(备忘录)
备忘录:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
Memento.h
//
// Created by thginWalker on 2023/12/9.
//
#ifndef BIG_TALK_DESIGN_MODE_MEMENTO_H
#define BIG_TALK_DESIGN_MODE_MEMENTO_H
#include <string>
class Memento {
private:
std::string state;
public:
[[nodiscard]] const std::string &getState() const {
return state;
};
void setState(const std::string &state) {
Memento::state = state;
};
public:
Memento() = default;
explicit Memento(const std::string &state) {
this->state = state;
};
};
#endif //BIG_TALK_DESIGN_MODE_MEMENTO_H
Originator.h
//
// Created by thginWalker on 2023/12/9.
//
#ifndef BIG_TALK_DESIGN_MODE_ORIGINATOR_H
#define BIG_TALK_DESIGN_MODE_ORIGINATOR_H
#include<string>
#include<iostream>
#include "Memento.h"
class Originator {
private:
std::string state;
public:
[[nodiscard]] const std::string &getState() const {
return state;
};
void setState(const std::string &_state) {
Originator::state = _state;
};
Memento *createMemento() {
return new Memento(state);
}
void setMemento(const Memento *memento) {
state = memento->getState();
}
void Show() {
std::cout << "State=" << state << std::endl;
}
};
#endif //BIG_TALK_DESIGN_MODE_ORIGINATOR_H
Caretaker.h
//
// Created by thginWalker on 2023/12/9.
//
#ifndef BIG_TALK_DESIGN_MODE_CARETAKER_H
#define BIG_TALK_DESIGN_MODE_CARETAKER_H
#include "Memento.h"
class Caretaker {
private:
Memento *memento{};
public:
Caretaker() = default;
[[maybe_unused]] explicit Caretaker(Memento *memento) : memento(memento) {};
[[nodiscard]] Memento *getMemento() const {
return memento;
};
void setMemento(Memento *_memento) {
Caretaker::memento = _memento;
};
};
#endif //BIG_TALK_DESIGN_MODE_CARETAKER_H
#include "Originator.h"
#include "Caretaker.h"
int main() {
auto *o = new Originator();
o->setState("On"); // Originator初始状态,状态属性为"On"
o->Show();
auto *c = new Caretaker();
// 保存状态时,由于有了很好的封装,可以隐藏Originator的实现细节
c->setMemento(o->createMemento());
o->setState("Off");
o->Show(); // Originator改变了状态属性为"Off"
o->setMemento(c->getMemento()); // 恢复原初始状态
o->Show(); // 恢复原初始状态
return 0;
}
Observer(观察者)
GOOD:定义了一种一对多的关系,让多个观察对象(公司员工)同时监听一个主题对象(秘书),主题对象状态发生变化时,会通知所有的观察者,使它们能够更新自己。
observer.h
#ifndef CLION_TEST_OBSERVER_H
#define CLION_TEST_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 //CLION_TEST_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 CLION_TEST_STATE_H
#define CLION_TEST_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 //CLION_TEST_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 CLION_TEST_STRATEGY_H
#define CLION_TEST_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 //CLION_TEST_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文章来源:https://www.toymoban.com/news/detail-704876.html
// 策略与工厂结合
Context(char cType) {
switch(cType) {
case '+': op = new AddOperation(3,8);
break;
default:
op = new AddOperation();
break;
}
}
main.h文章来源地址https://www.toymoban.com/news/detail-704876.html
int main()
{
int a,b;
cin>>a>>b;
Context *test=new Context('+');
cout<<test>GetResult()<<endl;
return 0;
}
Visitor(访问者)
后记
到了这里,关于《C++设计模式》——行为型的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!