一、职责链模式
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
示例:
//抽象处理者
class Handler {
public:virtual bool handleRequest(int days) = 0;virtual ~Handler() {}
};//小组组长(具体处理者)
class TeamLeader :public Handler {
public:virtual bool handleRequest(int days) override {if (days <= 3) {cout << "小组组长批准了请假申请,请假天数为:" << days << "天\n" << endl;return true;}cout << "小组组长无权批准,将请假申请转交给上级" << endl;return false;}
};//部门经理(具体处理者)
class DepartmentManager :public Handler {
public:virtual bool handleRequest(int days) override {if (days > 3 && days <=7) {cout << "部门经理批准了请假申请,请假天数为:" << days << "天\n" << endl;return true;}cout << "部门经理无权批准,将请假申请转交给上级" << endl;return false;}
};//公司总经理(具体处理者)
class GeneralManager :public Handler {
public:virtual bool handleRequest(int days) override {if (days > 7) {cout << "总经理批准了请假申请,请假天数为:" << days << "天\n" << endl;return true;}}
};//职责链管理类
class HandlerChain {
private:list<Handler*> handlers;
public:HandlerChain() {handlers.emplace_back(new TeamLeader());handlers.emplace_back(new DepartmentManager());handlers.emplace_back(new GeneralManager());}~HandlerChain() {for (auto handler : handlers) {delete handler;}}void handleRequest(int days) {for (auto handler : handlers) {if (handler->handleRequest(days))break;}}
};
测试代码:
HandlerChain chain;
int days[] { 2, 5, 10 };
for (auto d : days) {
chain.handleRequest(d);
}
输出结果:
小组组长批准了请假申请,请假天数为:2天小组组长无权批准,将请假申请转交给上级
部门经理批准了请假申请,请假天数为:5天小组组长无权批准,将请假申请转交给上级
部门经理无权批准,将请假申请转交给上级
总经理批准了请假申请,请假天数为:10天
二、命令模式
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。
示例:
//军队(接收者)
class Army {
public:void attack() {cout << "军队发动进攻!" << endl;}void retreat() {cout << "军队进行撤退!" << endl;}
};//抽象命令
class Command {
protected:Army* army;
public:Command(Army* a) :army(a) {}virtual void execute() = 0;virtual ~Command() {}
};//进攻命令(具体命令)
class AttackCmd :public Command {
public:using Command::Command;void execute() override {army->attack();}
};//撤退命令(具体命令)
class RetreatCmd :public Command {
public:using Command::Command;void execute() override {army->retreat();}
};//将军(调用者)
class General {
private:Command* command;
public:void setCommand(Command* c) {command = c;}void issueOrder() {if (command) {command->execute();}}
};
测试代码:
Army* army = new Army();
General* general = new General();Command* attack = new AttackCmd(army);
general->setCommand(attack);
general->issueOrder();
Command* retreat = new RetreatCmd(army);
general->setCommand(retreat);
general->issueOrder();delete attack;
delete retreat;
delete general;
delete army;
输出结果:
军队发动进攻!
军队进行撤退!
三、访问者模式
表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
示例:
class Visitor;//图形类(抽象元素)
class Shape {
public:virtual void accept(Visitor* v) = 0;virtual ~Shape() {}
};//圆形(具体元素)
class Circle :public Shape {
private:double radius;
public:Circle(double r) :radius(r) {}virtual void accept(Visitor* v) override;double getRadius() {return radius;}
};//矩形(具体元素)
class Rectangle :public Shape {
private:double width;double height;
public:Rectangle(double w, double h) :width(w), height(h) {}virtual void accept(Visitor* v) override;double getWidth() {return width;}double getHeight() {return height;}
};//抽象访问者
class Visitor {
public:virtual void visitCircle(Circle* c) = 0;virtual void visitRectangle(Rectangle* r) = 0;virtual ~Visitor() {}
};void Circle::accept(Visitor* v) {v->visitCircle(this);
}
void Rectangle::accept(Visitor* v) {v->visitRectangle(this);
}//计算面积(具体访问者)
class Calculator :public Visitor {
public:virtual void visitCircle(Circle* c) override {double area = 3.14159 * c->getRadius() * c->getRadius();cout << "圆的面积是:" << area << endl;}virtual void visitRectangle(Rectangle* r) override {double area = r->getHeight() * r->getWidth();cout << "矩形的面积是:" << area << endl;}
};//绘制轮廓(具体访问者)
class Outline :public Visitor {
public:virtual void visitCircle(Circle* c) override {cout << "绘制圆" << endl;}virtual void visitRectangle(Rectangle* r) override {cout << "绘制矩形" << endl;}
};//绘图(对象结构类)
class Drawing {
private:vector<Shape*> shapes;
public:~Drawing() {for (auto s : shapes) {delete s;}}void addShape(Shape* s) {shapes.emplace_back(s);}void accept(Visitor* v) {for (Shape* s : shapes) {s->accept(v);}}
};
测试代码:
Drawing* draw = new Drawing();
Circle* circle = new Circle(5.0);
Rectangle* rect = new Rectangle(4.0, 6.0);
draw->addShape(circle);
draw->addShape(rect);
Calculator* calculator = new Calculator();
draw->accept(calculator);
Outline* outline = new Outline();
draw->accept(outline);
delete outline;
delete calculator;
delete draw;
输出结果:
圆的面积是:78.5397
矩形的面积是:24
绘制圆
绘制矩形