行为型模式
行为型模式关注于对象之间的通信。
责任链模式
使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成一条链路,并沿着这条链传递该请求,直到有一个对象处理它为止。
class Handler {
protected:
Handler* successor;
public:
void setSuccessor(Handler* successor) {
this->successor = successor;
}
virtual void HandleRequest(int request) = 0;
};
class ConcreteHandler1 : public Handler {
public:
void HandleRequest(int request) override {
if (request <= 10) {
for (int i = 0; i <= 10; ++i) {
cout << "HandleRequest1 handle " << i << endl;
}
} else if (this->successor) {
this->successor->HandleRequest(request);
}
}
};
class ConcreteHandler2 : public Handler {
public:
void HandleRequest(int request) override {
if (request > 10 && request <= 20) {
for (int i = 10; i <= 20; ++i) {
cout << "HandleRequest2 handle " << i << endl;
}
} else if (this->successor) {
this->successor->HandleRequest(request);
}
}
};
class ConcreteHandler3 : public Handler {
public:
void HandleRequest(int request) override {
if (request > 20 && request <= 30) {
for (int i = 20; i <= 30; ++i) {
cout << "HandleRequest3 handle " << i << endl;
}
} else if (this->successor) {
this->successor->HandleRequest(request);
}
}
};
// 使用
ConcreteHandler1 handle1;
ConcreteHandler2 handle2;
ConcreteHandler3 handle3;
handle1.setSuccessor(&handle2);
handle2.setSuccessor(&handle3);
handle1.HandleRequest(30);
命令模式
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或者记录记录日志,以及支持可撤销的操作。
class Allocator {
public:
template <typename T>
void Execute(T t) {
// t 是一个返回类型为 可打印类型的可调用对象
cout << "Allocator 执行:" << t() << endl;
}
};
class Command {
protected:
Allocator alloc;
public:
void bind(Allocator& alloc) {
this->alloc = alloc;
}
virtual void Execute() = 0;
};
class MemeryCommand : public Command {
public:
void Execute() override {
this->alloc.Execute([]() {
return "获取内存资源";
});
}
};
class PortCommand : public Command {
public:
void Execute() override {
this->alloc.Execute([]() {
return "获取端口资源";
});
}
};
class Invoke {
Allocator alloc;
list<Command*> commandList;
size_t memery = 500; // 内存资源一共 500 MB
size_t port = 3; // 端口资源一共3个
public:
Invoke(Allocator& alloc)
: alloc(alloc) { }
void addCommand(Command* cmd) {
if (dynamic_cast<MemeryCommand*>(cmd)) {
// 若请求的是内存资源
if (memery > 0) {
// 若内存资源充足
commandList.push_back(cmd);
memery -= 200;
} else {
cout << "内存资源不足" << endl;
}
} else {
// 否则请求的为端口资源
if (port > 0) {
commandList.push_back(cmd);
port -= 1;
} else {
cout << "端口资源不足" << endl;
}
}
}
void rollback(Command* cmd) {
commandList.remove(cmd);
}
void commit() {
for (auto cmd : commandList) {
cmd->bind(alloc);
cmd->Execute();
}
}
};
// 使用
Allocator alloc;
Invoke in(alloc);
MemeryCommand mcmd1;
MemeryCommand mcmd2;
PortCommand pcmd1;
PortCommand pcmd2;
PortCommand pcmd3;
PortCommand pcmd4;
in.addCommand(&mcmd1);
in.addCommand(&mcmd2);
in.addCommand(&pcmd1);
in.addCommand(&pcmd2);
in.addCommand(&pcmd3);
in.addCommand(&pcmd4);
in.rollback(&pcmd3);
in.commit();
解释器模式
解释器模式:给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。
如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题
迭代器模式
迭代器模式提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。
中介者模式
中介者模式是迪米特法则的践行者,通过在复杂系统中引入中介者来简化系统结构。通过引入中介者,将复杂的网状交互转变为更加简单的星状交互。
备忘录模式
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
struct State {
int hp;
int mp;
};
class Memento {
State state;
public:
void setMemento(const State& state) {
this->state = state;
}
const State getState() {
return state;
}
};
class Player {
State state;
int id;
public:
Memento* createMemento() {
return new Memento;
}
void setMemento(Memento* mem) {
mem->setMemento(state);
}
};
class CareTaker {
Memento* mem = nullptr;
public:
void setMemento(Memento* mem) {
this->mem = mem;
}
Memento* getMemento() {
return this->mem;
}
};
// 使用
Player player;
CareTaker taker;
taker.setMemento(player.createMemento());
player.setMemento(taker.getMemento());
观察者模式
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主体对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
class Subject;
class Observer {
protected:
Subject* sub;
public:
virtual void update() = 0;
};
class Subject {
list<Observer*> obs;
public:
void add(Observer* ob) {
obs.push_back(ob);
}
void del(Observer* ob) {
obs.remove(ob);
}
void onStateChanged() {
for (auto ob : obs) {
ob->update();
}
}
};
class BinaryObserver : Observer {
public:
BinaryObserver(Subject* sub) {
sub->add(this);
}
void update() override {
cout << "updated" << endl;
}
};
//使用
Subject* sub = new Subject;
BinaryObserver bin(sub);
sub->onStateChanged();
状态模式
class Context;
class State {
public:
virtual void doAction(Context& context) = 0;
};
class Context {
State* state = nullptr;
public:
void setState(State* state) {
this->state = state;
}
State* getState() {
return this->state;
}
};
class StartState : State {
public:
void doAction(Context& context) override {
cout << "Start" << endl;
context.setState(this);
}
};
class EndState : State {
public:
void doAction(Context& context) override {
cout << "End" << endl;
context.setState(this);
}
};
// 使用
Context context;
StartState start;
start.doAction(context);
EndState end;
end.doAction(context);
空对象模式
策略模式
策略模式用于将操纵抽象成类,用于减少条件语句的产生。
struct Strategy {
virtual int Op(int num1, int num2) = 0;
};
class Plus : Strategy {
public:
int Op(int num1, int num2) override {
return num1 + num2;
}
};
class Minus : Strategy {
public:
int Op(int num1, int num2) override {
return num1 - num2;
}
};
// 使用
Plus pl;
cout << pl.Op(10, 20) << endl;
Minus mi;
cout << mi.Op(20, 30) << endl;
模板模式
在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。实际上就是使用超类接口操纵子类对象。
访问者模式
在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作。