C++进阶(语法篇)—第11章 设计模式(2)

11.3行为型模式

行为型模式:主要用于管理对象之间的算法、关系和职责。主要讲策略模式、命令模式、观察者模式、模板模式。

11.3.1策略模式

策略模式:定义一系列算法,将这些算法封装起来,并且使算法之间可以转换。本质是将算法和客户端之间隔离,使得客户端只能通过抽象算法类来访问具体算法。

假设手机需要支持3种使用模式,分别是标准模式、驾车模式、飞行模式。现在你是手机的开发者,该如何设计应用程序?如果将来手机还要支持静音模式,又该如何设计?

#include <iostream>

 

using namespace std;

 

//模式:接口

class Mode

{

public:

virtual ~Mode(){}

virtual void UseMode(void) = 0;

};

//标准模式

class StandardMode:public Mode

{

public:

virtual void UseMode(void){cout<<"Standard Mode!"<<endl;};

};

//驾车模式

class DrivingMode:public Mode

{

public:

virtual void UseMode(void){cout<<"Driving Mode!"<<endl;};

};

//飞行模式

class FlightMode:public Mode

{

public:

virtual void UseMode(void){cout<<"Flight Mode!"<<endl;};

};

//手机模式

class PhoneMode

{

private:

Mode * mode;

public:

PhoneMode(Mode * mode)

{

this->mode = mode;

}

void UseMode()

{

mode->UseMode();

}

};

 

int main(int argc,char ** argv)

{

StandardMode * sm = new StandardMode;

DrivingMode * dm = new DrivingMode;

FlightMode * fm = new FlightMode;

 

PhoneMode pm1(sm);

PhoneMode pm2(dm);

PhoneMode pm3(fm);

pm1.UseMode();

pm2.UseMode();

pm3.UseMode();

 

delete sm;

delete dm;

delete fm;

 

return 0;

}

运行结果:

Standard Mode!

Driving Mode!

Flight Mode!

策略模式结构图:

Context:环境角色,持有一个对Stratery的引用,最终给客户端使用。相当于PhoneMode。

Stratery:抽象策略类,相当于Mode。

ConcreteStratery:具体策略类,相当于StandardMode、DrivingMode、FlightMode。

策略模式和简单工厂模式看起来很相似,都是通过多态来实现不同子类的选取。简单工厂模式是工厂根据需求来创建对象(产品),然后将事情交给对象去完成。策略模式是环境角色根据自己选择的策略来创建对象,这个对象是其本身,因此所有的事情还是自己来完成。难以理解的话,可以看看模式结构图。

11.3.2命令模式

餐馆服务员接收到一份订单:客户要求先来一份烤肉再来一份炒菜(烤肉在前,炒菜在后);服务员接收到烤肉命令和炒菜命令,然后执行命令(但命令的真正实现不是服务员);厨师接收到烤肉命令和炒菜命令后,开始干活。

//Receiver.h

#pragma once

#include <iostream>

using namespace std;

//厨师

class Cook

{

public:

//烤肉

void Barbecue(void)

{

cout << "Barbecue..." << endl;

}

//炒菜

void StirFry(void)

{

cout << "StirFry" << endl;

}

};

//Command.h

#pragma once

#include "Receiver.h"

class Command

{

public:

Command() {}

Command(Cook * cook)

{

this->cook = cook;

}

virtual void execute(void) = 0;

protected:

Cook * cook;

};

//烤肉命令

class BarbecueCommand :public Command

{

public:

BarbecueCommand() {}

BarbecueCommand(Cook * cook)

{

this->cook = cook;

}

void execute(void)

{

cout << "BarbecueCommand::execute" << endl;

cook->Barbecue();

}

};

 

class StirFryCommand :public Command

{

public:

StirFryCommand() {}

StirFryCommand(Cook * cook)

{

this->cook = cook;

}

void execute(void)

{

cout << "StirFryCommand::execute" << endl;

cook->StirFry();

}

};

//Invoker.h

#pragma once

#include "Command.h"

#include <list>

class Waiter

{

public:

Waiter() {};

// 添加命令

void addCmd(Command *cmd)

{

cmds.push_back(cmd);

}

// 删除命令

void deleteCmd(Command *cmd)

{

cmds.remove(cmd);

}

// 执行命令

void notify()

{

for (list<Command *>::iterator it = cmds.begin(); it != cmds.end(); ++it)

{

(*it)->execute();

}

}

 

private:

std::list<Command *> cmds;  // 命令队列

};

//main.cpp

#include <iostream>

#include "Invoker.h"

#include "Receiver.h"

#include "Command.h"

 

using namespace std;

 

int main(int argc, char ** argv)

{

Cook * ck = new Cook;

BarbecueCommand * pBarCom = new BarbecueCommand(ck);

StirFryCommand * pStiCom = new StirFryCommand(ck);

 

Waiter wait;

wait.addCmd(pBarCom);

wait.addCmd(pStiCom);

wait.notify();

 

delete ck;

delete pBarCom;

delete pStiCom;

return 0;

}

运行结果:

BarbecueCommand::execute

Barbecue...

StirFryCommand::execute

StirFry

命令模式结构图:

Invoker:命令的持有者和执行者;

Command:命令的抽象类;

ConcreteCommand:命令的具体类;

Receiver:命令的接收者和实际执行者;

命令模式难以理解,举个实际例子:打车客户(Client)发出打车命令->滴滴平台(Invoker)接收到命令,然后发出打车命令->滴滴师傅(Receiver)接收到打车命令,然后去目标地点接人。通用例子:Client发出命令->Invoker持有,加入命令队列,然后执行命令->Receiver接收和开始干活。

11.3.3观察者模式

观察者模式:定义对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象得到通知并自动更新。

假设小明爸爸和小明妈妈关注小明的成绩,当小明考试成绩出来时,需要及时通知小明的父母,该如何设计这个程序?

#include <iostream>

#include <list>

using namespace std;

 

class Subject;

class Observer;

 

//抽象目标:Subject

class Subject

{

public:

virtual void Attach(Observer *) = 0;//注册观察者

virtual void Detach(Observer *) = 0;//注销观察者

virtual void Notify() = 0;//通知观察者

};

//抽象观察者:Observer

class Observer

{

public:

virtual void Update(double) = 0;//更新状态

};

//具体目标:ConcreteSubject

class Student : public Subject

{

private:

list<Observer *> pObserverList;//观察者列表

double achievement;

public:

void Attach(Observer * pObserver)

{

pObserverList.push_back(pObserver);

}

void Detach(Observer * pObserver)

{

pObserverList.remove(pObserver);

}

void Notify()

{

for(list<Observer *>::iterator it = pObserverList.begin(); it != pObserverList.end(); ++it)

{

(*it)->Update(achievement);

}

}

void setValue(double achievement)

{

this->achievement = achievement;

}

};

//具体观察者:ConcreteObserver

class Father :public Observer

{

private:

Subject * pSubject;

public:

Father() {}

Father(Subject * pSubject)

{

this->pSubject = pSubject;

}

void Update(double achievement)

{

cout <<"孩子成绩:" << achievement << endl;

}

};

class Mother : public Observer

{

private:

Subject * pSubject;

public:

Mother() {}

Mother(Subject * pSubject)

{

this->pSubject = pSubject;

}

void Update(double achievement)

{

cout << "孩子成绩:" << achievement << endl;

}

};

 

int main(int argc, char ** argv)

{

//创建具体目标

Student * xiaoming = new Student();

xiaoming->setValue(60);

 

//创建具体观察者

Father * xmF = new Father(xiaoming);

Mother * xmM = new Mother(xiaoming);

 

//加入观察队列

xiaoming->Attach(xmF);

xiaoming->Attach(xmM);

 

//通知观察者

xiaoming->Notify();

 

delete xiaoming;

delete xmF;

delete xmM;

return 0;

}

运行结果:

孩子成绩:60

孩子成绩:60

观察者模式结构图:

Subject(抽象目标):知道所有观察者,并提供注册和删除观察者的接口;

Observer(抽象观察者):为具体观察者提供接口,在得到目标的通知时进行自我更新。

ConcreteSubject(具体目标):当具体目标的状态发生改变,通知所有观察者。

ConcreteObserver(具体观察者):实现更新接口Update。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值