行为型模式:用来对类或对象怎样交互和怎样分配职责进行描述
1、模板模式
在抽象类中统一操作步骤,并规定好接口,让子类实现接口,这样可以把各个具体的子类和操作步骤解耦合
#include <iostream>
using namespace std;
class MakeCar
{
public:
virtual void MakeHead() = 0;
virtual void MakeBody() = 0;
virtual void MakeTail() = 0;
public:
void Make() //模板函数 把业务逻辑给做好
{
MakeTail();
MakeBody();
MakeHead();
}
};
//
class Jeep : public MakeCar
{
public:
virtual void MakeHead()
{
cout << "jeep head" << endl;
}
virtual void MakeBody()
{
cout << "jeep body" << endl;
}
virtual void MakeTail()
{
cout << "jeep tail" << endl;
}
};
class Bus : public MakeCar
{
public:
virtual void MakeHead()
{
cout << "Bus head" << endl;
}
virtual void MakeBody()
{
cout << "Bus body" << endl;
}
virtual void MakeTail()
{
cout << "Bus tail" << endl;
}
};
void main()
{
MakeCar *car = new Bus;
car->Make();
delete car;
MakeCar *car2 = new Jeep;
car2->Make();
delete car2;
cout<<"hello..."<<endl;
system("pause");
return ;
}
2、命令模式
Command模式也叫命令模式 ,是行为设计模式的一种。Command模式通过被称为
Command的类封装了对目标对象的调用行为以及调用参数。
在面向对象的程序设计中,一个对象调用另一个对象,一般情况下的调用过程是:创建目标对象实例;设置调用参数;调用目标对象的方法。
但在有些情况下有必要使用一个专门的类对这种调用过程加以封装,我们把这种专门的类称作command类。
适用于:
是将一个请求封装为一个对象,从而使你可用不同的请求对客户端进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
#include <iostream>
using namespace std;
class Doctor
{
public:
void treat_eye()
{
cout << "医生 治疗 眼科病" << endl;
}
void treat_nose()
{
cout << "医生 治疗 鼻科病" << endl;
}
};
class CommandTreatEye
{
public:
CommandTreatEye(Doctor *doctor)
{
m_doctor = doctor;
}
void treat()
{
m_doctor->treat_eye();
}
private:
Doctor *m_doctor;
};
class CommandTreatNose
{
public:
CommandTreatNose(Doctor *doctor)
{
m_doctor = doctor;
}
void treat()
{
m_doctor->treat_nose();
}
private:
Doctor *m_doctor;
};
void main21_1()
{
//1 医生直接看病
/*
Doctor *doctor = new Doctor ;
doctor->treat_eye();
delete doctor;
*/
//2 通过一个命令 医生通过 命令 治疗 治病
Doctor *doctor = new Doctor ;
CommandTreatEye * commandtreateye = new CommandTreatEye(doctor); //shift +u //转小写 shift+ctl + u转大写
commandtreateye->treat();
delete commandtreateye;
delete doctor;
return ;
}
void main()
{
main21_1();
cout<<"hello..."<<endl;
system("pause");
return ;
}
#include <iostream>
using namespace std;
#include "list"
class Doctor
{
public:
void treat_eye()
{
cout << "医生 治疗 眼科病" << endl;
}
void treat_nose()
{
cout << "医生 治疗 鼻科病" << endl;
}
};
class Command
{
public:
virtual void treat() = 0;
};
class CommandTreatEye : public Command
{
public:
CommandTreatEye(Doctor *doctor)
{
m_doctor = doctor;
}
void treat()
{
m_doctor->treat_eye();
}
private:
Doctor *m_doctor;
};
class CommandTreatNose : public Command
{
public:
CommandTreatNose(Doctor *doctor)
{
m_doctor = doctor;
}
void treat()
{
m_doctor->treat_nose();
}
private:
Doctor *m_doctor;
};
class BeautyNurse
{
public:
BeautyNurse(Command *command)
{
this->command = command;
}
public:
void SubmittedCase() //提交病例 下单命令
{
command->treat();
}
protected:
private:
Command *command;
};
//护士长
class HeadNurse
{
public:
HeadNurse()
{
m_list.clear();
}
public:
void setCommand(Command *command)
{
m_list.push_back(command);
}
void SubmittedCase() //提交病例 下单命令
{
for (list<Command *>::iterator it=m_list.begin(); it!=m_list.end(); it++)
{
(*it)->treat();
}
}
private:
list<Command *> m_list;
};
void main21_1()
{
//1 医生直接看病
/*
Doctor *doctor = new Doctor ;
doctor->treat_eye();
delete doctor;
*/
//2 通过一个命令 医生通过 命令 治疗 治病
Doctor *doctor = new Doctor ;
Command * command = new CommandTreatEye(doctor); //shift +u //转小写 shift+ctl + u转大写
command->treat();
delete command;
delete doctor;
return ;
}
void main21_2()
{
//3 护士提交简历 给以上看病
BeautyNurse *beautynurse = NULL;
Doctor *doctor = NULL;
Command *command = NULL;
doctor = new Doctor ;
//command = new CommandTreatEye(doctor); //shift +u //转小写 shift+ctl + u转大写
command = new CommandTreatNose(doctor); //shift +u //转小写 shift+ctl + u转大写
beautynurse = new BeautyNurse(command);
beautynurse->SubmittedCase();
delete doctor;
delete command;
delete beautynurse;
return ;
}
//4 通过护士长 批量的下单命令
void main21_3()
{
//护士提交简历 给以上看病
HeadNurse *headnurse = NULL;
Doctor *doctor = NULL;
Command *command1 = NULL;
Command *command2 = NULL;
doctor = new Doctor ;
command1 = new CommandTreatEye(doctor); //shift +u //转小写 shift+ctl + u转大写
command2 = new CommandTreatNose(doctor); //shift +u //转小写 shift+ctl + u转大写
headnurse = new HeadNurse(); //new 护士长
headnurse->setCommand(command1);
headnurse->setCommand(command2);
headnurse->SubmittedCase(); // 护士长 批量下单命令
delete doctor;
delete command1;
delete command2;
delete headnurse;
return ;
}
void main()
{
//main21_1();
//main21_2();
main21_3();
cout<<"hello..."<<endl;
system("pause");
return ;
}
3 、责任链模式
#include <iostream>
using namespace std;
/*
struct Teacher
{
char name;
int age;
Teacher *next;
};
*/
//造完车 以后,需要把任务 传递下去
class CarHandle
{
public:
virtual void HandleCar() = 0;
CarHandle *setNextHandle(CarHandle *handle)
{
m_handle = handle;
return m_handle;
}
protected:
CarHandle *m_handle; //下一个处理单元
};
class HeadCarHandle : public CarHandle
{
public:
virtual void HandleCar()
{
cout << "造车头" << endl;
//造 玩车头 以后 把任务递交给 下一个处理者
if (m_handle != NULL)
{
m_handle->HandleCar(); //
}
}
};
class BodyCarHandle : public CarHandle
{
public:
virtual void HandleCar()
{
cout << "造 车身" << endl;
//造 造 车身 以后 把任务递交给 下一个处理者
if (m_handle != NULL)
{
m_handle->HandleCar(); //
}
}
};
class TailCarHandle : public CarHandle
{
public:
virtual void HandleCar()
{
cout << "造车尾" << endl;
//造 造车尾 以后 把任务递交给 下一个处理者
if (m_handle != NULL)
{
m_handle->HandleCar(); //
}
}
};
void main()
{
CarHandle *headHandle = new HeadCarHandle;
CarHandle *bodyHandle = new BodyCarHandle;
CarHandle *tailHandle = new TailCarHandle;
//任务的处理关系
/*
headHandle->setNextHandle(bodyHandle);
bodyHandle->setNextHandle(tailHandle);
tailHandle->setNextHandle(NULL);
*/
headHandle->setNextHandle(tailHandle);
tailHandle->setNextHandle(bodyHandle);
bodyHandle->setNextHandle(NULL);
headHandle->HandleCar();
/*
//业务逻辑 写死在客户端了..
headHandle->HandleCar();
bodyHandle->HandleCar();
tailHandle->HandleCar();
*/
delete headHandle;
delete bodyHandle;
delete tailHandle;
cout<<"hello..."<<endl;
system("pause");
return ;
}
4、策略模式
Strategy:
策略(算法)抽象。
ConcreteStrategy
各种策略(算法)的具体实现。
Context
策略的外部封装类,或者说策略的容器类。根据不同策略执行不同的行为。策略由外部环境决定。
适用于:
准备一组算法,并将每一个算法封装起来,使得它们可以互换。
#include <iostream>
using namespace std;
class Strategy
{
public:
virtual void crypt() = 0;
};
//对称加密 速度快 加密大数据块文件 特点:加密密钥和解密密钥是一样的.
//非对称加密 加密速度慢 加密强度高 高安全性高 ;特点: 加密密钥和解密密钥不一样 密钥对(公钥 和 私钥)
//
class AES : public Strategy
{
public:
virtual void crypt()
{
cout << "AES加密算法" << endl;
}
};
class DES : public Strategy
{
public:
virtual void crypt()
{
cout << "DES 加密算法" << endl;
}
};
class Context
{
public:
void setStrategy(Strategy *strategy)
{
this->strategy = strategy;
}
void myoperator()
{
strategy->crypt();
}
protected:
private:
Strategy *strategy;
};
void main()
{
/*
//1
DES *des = new DES;
des->crypt();
delete des;
*/
Strategy *strategy = NULL;
//strategy = new DES;
strategy = new AES;
Context *context = new Context;
context->setStrategy(strategy);
context->myoperator();
delete strategy;
delete context;
cout<<"hello..."<<endl;
system("pause");
return ;
}
5、中介模式
适用于:
用一个中介对象,封装一些列对象(同事)的交换,中介者是各个对象不需要显示的相互作用,从而实现了耦合松散,而且可以独立的改变他们之间的交换。
#include <iostream>
using namespace std;
#include "string"
class Mediator;
class Person
{
public:
Person(string name, int sex, int condi, Mediator *m)
{
m_name = name;
m_sex = sex;
m_condi = condi;
mediator = m;
}
string getName()
{
return m_name;
}
int getSex()
{
return m_sex;
}
int getCondi()
{
return m_condi;
}
virtual void getParter(Person *p) = 0;
protected:
string m_name;
int m_sex;
int m_condi;
Mediator *mediator;
};
class Mediator
{
public:
void setMan(Person *man)
{
pMan = man;
}
void setWoman(Person *woman)
{
pWoman = woman;
}
public:
virtual void getParter()
{
if (pWoman->getSex() == pMan->getSex())
{
cout << "同性恋 之间 不能找对象 " << endl;
}
if (pWoman->getCondi() == pMan->getCondi() )
{
cout << pWoman->getName() << " 和 " << pMan->getName() << "绝配 " <<endl;
}
else
{
cout << pWoman->getName() << " 和 " << pMan->getName() << "不配 " <<endl;
}
}
private:
private:
Person *pMan;
//list<Person *> m_list;
Person *pWoman; //
};
class Woman : public Person
{
public:
Woman(string name, int sex, int condi, Mediator *m) : Person(name, sex, condi, m)
{
}
virtual void getParter(Person *p)
{
mediator->setMan(p);
mediator->setWoman(this);
mediator->getParter(); //找对象
}
};
class Man : public Person
{
public:
Man(string name, int sex, int condi, Mediator *m) : Person(name, sex, condi, m)
{
}
virtual void getParter(Person *p)
{
mediator->setMan(this);
mediator->setWoman(p);
mediator->getParter(); //找对象
}
};
void main()
{
//string name, int sex, int condi
Mediator *m = new Mediator;
Person *xiaofang = new Woman("小芳", 2, 5, m);
Person *zhangsan = new Man("张三", 1, 4, m);
Person *lisi = new Man("李四", 1, 5, m);
xiaofang->getParter(zhangsan);
xiaofang->getParter(lisi);
cout<<"hello..."<<endl;
system("pause");
return ;
}
6、观察者模式
一对多的关系,一个改变通知所有的
被观察者持有观察者的引用,当被观察者发生变化,notify所有观察者
适用于:
定义对象间一种一对多的依赖关系,使得每一个对象改变状态,则所有依赖于他们的对象都会得到通知。
#include <iostream>
using namespace std;
#include "string"
#include "list"
class Secretary;
//观察者
class PlayserObserver
{
public:
PlayserObserver(Secretary *secretary)
{
this->m_secretary = secretary;
}
void update(string action)
{
cout << "action:" << action << endl;
cout << "老板来了 我很害怕啊..." << endl;
}
private:
Secretary *m_secretary;
};
//
class Secretary
{
public:
Secretary()
{
m_list.clear();
}
void Notify(string info)
{
//给所有的 观察者 发送 情报
for ( list<PlayserObserver *>::iterator it=m_list.begin(); it!=m_list.end(); it++)
{
(*it)->update(info); //
}
}
void setPlayserObserver(PlayserObserver *o)
{
m_list.push_back(o);
}
private:
list<PlayserObserver *> m_list;
};
void main()
{
Secretary *secretary = NULL;
PlayserObserver *po1 = NULL;
PlayserObserver *po2 = NULL;
secretary = new Secretary;
po1 = new PlayserObserver(secretary);
po2 = new PlayserObserver(secretary);
secretary->setPlayserObserver(po1);
secretary->setPlayserObserver(po2);
secretary->Notify("老板来了") ;
secretary->Notify("老板走了");
delete secretary ;
delete po1 ;
delete po2 ;
system("pause");
return ;
}
7、备忘录模式
是保存对象的内部状态,并在需要的时候(undo/rollback)恢复对象以前的状态。
Originator(原生者)
需要被保存状态以便恢复的那个对象。
Memento(备忘录)
该对象由Originator创建,主要用来保存Originator的内部状态。
Caretaker(管理者)
负责在适当的时间保存/恢复Originator对象的状态。
适用于:
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样就可以将以后的对象状态恢复到先前保存的状态。
适用于功能比较复杂的,但需要记录或维护属性历史的类;或者需要保存的属性只是众多属性中的一小部分时Originator可以根据保存的Memo还原到前一状态。
#include <iostream>
using namespace std;
#include "string"
//Caretaker 管理者
// MememTo 备忘录
class MememTo
{
public:
MememTo(string name,int age )
{
m_name = name;
m_age = age;
}
string getName()
{
return m_name;
}
int getAge()
{
return m_age;
}
void setName(string name)
{
this->m_name = name;
}
void setAge(int age)
{
this->m_age = age;
}
private:
string m_name;
int m_age;
};
class Person
{
public:
Person(string name,int age )
{
m_name = name;
m_age = age;
}
string getName()
{
return m_name;
}
int getAge()
{
return m_age;
}
void setName(string name)
{
this->m_name = name;
}
void setAge(int age)
{
this->m_age = age;
}
//保存
MememTo* createMememTo()
{
return new MememTo(m_name, m_age);
}
//还原
void setMememTo(MememTo* memto)
{
this->m_age = memto->getAge();
this->m_name = memto->getName();
}
public:
void printT()
{
cout << "m_name:" << m_name << " m_age:" << m_age << endl;
}
private:
string m_name;
int m_age;
};
class Caretaker
{
public:
Caretaker(MememTo *memto)
{
this->memto = memto;
}
MememTo *getMememTo()
{
return memto;
}
void setMememTo(MememTo *memto)
{
this->memto = memto;
}
protected:
private:
MememTo *memto;
};
void main26_02()
{
//MememTo *memto = NULL;
Caretaker *caretaker = NULL;
Person *p = new Person("张三", 32);
p->printT();
//创建 Person对象的一个状态
printf("---------\n");
caretaker = new Caretaker( p->createMememTo());
p->setAge(42);
p->printT();
printf("还原旧的状态\n" );
p->setMememTo(caretaker->getMememTo());
p->printT();
delete caretaker;
delete p;
}
void main26_01()
{
MememTo *memto = NULL;
Person *p = new Person("张三", 32);
p->printT();
//创建 Person对象的一个状态
printf("---------\n");
memto = p->createMememTo();
p->setAge(42);
p->printT();
printf("还原旧的状态\n" );
p->setMememTo(memto);
p->printT();
delete memto;
delete p;
}
void main()
{
//main26_01();
main26_02();
system("pause");
return ;
}
8、访问者模式
不同的动作访问不同的数据结构;
比如有一个公园,有一到多个不同的组成部分;该公园存在多个访问者:清洁工A负责打扫公园的A部分,清洁工B负责打扫公园的B部分,公园的管理者负责检点各项事务是否完成,上级领导可以视察公园等等。也就是说,对于同一个公园,不同的访问者有不同的行为操作,而且访问者的种类也可能需要根据时间的推移而变化(行为的扩展性)。
适用于:
把数据结构 和 作用于数据结构上的操作 进行解耦合;
适用于数据结构比较稳定的场合
访问者模式总结:
访问者模式优点是增加新的操作很容易,因为增加新的操作就意味着增加一个新的访问者。访问者模式将有关的行为集中到一个访问者对象中。
那访问者模式的缺点是是增加新的数据结构变得困难了
#include <iostream>
using namespace std;
#include "list"
// Visitor ParkElement
class ParkElement;
class Visitor
{
public:
virtual void visit(ParkElement *parkelement) = 0;
};
class ParkElement
{
public:
virtual void accept(Visitor *visit) = 0;
};
class ParkA : public ParkElement
{
public:
virtual void accept(Visitor *v)
{
v->visit(this); //公园接受访问者访问 让访问者做操作
}
};
class ParkB : public ParkElement
{
public:
virtual void accept(Visitor *v)
{
v->visit(this); //公园接受访问者访问 让访问者做操作
}
};
//整个公园
class Park : public ParkElement
{
public:
Park()
{
m_list.clear();
}
void setParkElement(ParkElement *pe)
{
m_list.push_back(pe);
}
public:
virtual void accept(Visitor *v)
{
//v->visit(this); //公园接受访问者访问 让访问者做操作
for (list<ParkElement *>::iterator it = m_list.begin(); it!=m_list.end(); it++ )
{
(*it)->accept(v); //公园A 公园B 接受 管理者v访问
}
}
private:
list<ParkElement *> m_list; //公园的每一部分 //应该让公园的每一个部分 都让 管理者访问
};
class VisitorA : public Visitor
{
public:
virtual void visit(ParkElement *parkelement)
{
cout << "清洁工A 完成 公园A部分的 打扫 " << endl; //parkelement->getName();
}
};
class VisitorB : public Visitor
{
public:
virtual void visit(ParkElement *parkelement)
{
cout << "清洁工B 完成 公园B部分的 打扫 " << endl; //parkelement->getName();
}
};
class ManagerVisitor : public Visitor
{
public:
virtual void visit(ParkElement *parkelement)
{
cout << "管理者 访问公园 的 各个部分 " << endl; //parkelement->getName();
}
};
void main27_01()
{
Visitor *vA = new VisitorA;
Visitor *vB = new VisitorB;
ParkA *parkA = new ParkA;
ParkB *parkB = new ParkB;
//
parkA->accept(vA);
parkB->accept(vB);
delete vA;
delete vB;
delete parkA;
delete parkB;
}
void main27_02()
{
Visitor *vManager = new ManagerVisitor ;
Park *park = new Park;
ParkElement *parkA = new ParkA;
ParkElement *parkB = new ParkB;
park->setParkElement(parkA);
park->setParkElement(parkB);
//整个公园 接受 管理者访问
park->accept(vManager);
delete parkA;
delete parkB;
delete park;
delete vManager;
}
void main()
{
//main27_01();
main27_02();
cout<<"hello..."<<endl;
system("pause");
return ;
}
9、状态模式
通过用户的状态来改变对象的行为
#include <iostream>
using namespace std;
class Worker;
class State
{
public:
virtual void doSomeThing(Worker *w) = 0;
};
class Worker
{
public:
Worker();
int getHour()
{
return m_hour;
}
void setHour(int hour) //改变状态 7
{
m_hour = hour;
}
State* getCurrentState()
{
return m_currstate;
}
void setCurrentState(State* state)
{
m_currstate = state;
}
void doSomeThing() //
{
m_currstate->doSomeThing(this);
}
private:
int m_hour;
State *m_currstate; //对象的当前状态
};
class State1 : public State
{
public:
void doSomeThing(Worker *w);
};
class State2 : public State
{
public:
void doSomeThing(Worker *w);
};
void State1::doSomeThing(Worker *w)
{
if (w->getHour() == 7 || w->getHour()==8)
{
cout << "吃早饭" << endl;
}
else
{
delete w->getCurrentState(); //状态1 不满足 要转到状态2
w->setCurrentState(new State2 );
w->getCurrentState()->doSomeThing(w); //
}
}
void State2::doSomeThing(Worker *w)
{
if (w->getHour() == 9 || w->getHour()==10)
{
cout << "工作" << endl;
}
else
{
delete w->getCurrentState(); //状态2 不满足 要转到状态3 后者恢复到初始化状态
w->setCurrentState(new State1); //恢复到当初状态
cout << "当前时间点:" << w->getHour() << "未知状态" << endl;
}
}
Worker::Worker()
{
m_currstate = new State1;
}
void main()
{
Worker *w1 = new Worker;
w1->setHour(7);
w1->doSomeThing();
w1->setHour(9);
w1->doSomeThing();
delete w1;
cout<<"hello..."<<endl;
system("pause");
return ;
}
解释模式
#include <iostream>
using namespace std;
// Context
// Expression
// PlusExpression MinusExpression
class Context
{
public:
Context(int num)
{
this->m_num = num;
}
int getNum()
{
return m_num;
}
int getRes()
{
return m_res;
}
void setNum(int num)
{
this->m_num = num;
}
void setRes(int res)
{
this->m_res = res;
}
private:
int m_num;
int m_res;
};
class Expression
{
public:
virtual void interpreter(Context *context) = 0;
private:
Context *m_context;
};
//╝Мие
class PlusExpression : public Expression
{
public:
PlusExpression()
{
this->context = NULL;
}
virtual void interpreter(Context *context)
{
int num = context->getNum();
num ++;
context->setNum(num);
context->setRes(num);
}
private:
Context *context;
};
// ╝ш ие
class MinusExpression : public Expression
{
public:
MinusExpression()
{
this->context = NULL;
}
virtual void interpreter(Context *context)
{
int num = context->getNum();
num -- ;
context->setNum(num);
context->setRes(num);
}
private:
Context *context;
};
void main()
{
Expression *expression = NULL;
Context *context = NULL;
Expression *expression2 = NULL;
context = new Context(10);
cout << context->getNum() << endl;
expression = new PlusExpression;
expression->interpreter(context);
cout << context->getRes() << endl;
//////////////////////////////////////////////////////////////////////////
expression2 = new MinusExpression;
expression2->interpreter(context);
cout << context->getRes() << endl;
cout<<"hello..."<<endl;
system("pause");
return ;
}
迭代器模式
在迭代器中 持有 一个集合的 引用;所以通过迭代器,就可以访问集合
#include <iostream>
using namespace std;
// MyIterator Aggregate ContreteIterator ConcreteAggregate
// a b c d
// ▲
typedef int Object ;
#define SIZE 5
class MyIterator
{
public:
virtual void First() = 0;
virtual void Next() = 0;
virtual bool IsDone() = 0;
virtual Object CurrentItem() = 0;
};
class Aggregate
{
public:
virtual MyIterator *CreateIterator() = 0;
virtual Object getItem(int index) = 0;
virtual int getSize() = 0;
};
class ContreteIterator : public MyIterator
{
public:
ContreteIterator(Aggregate *ag)
{
_ag = ag;
_current_index = 0;
}
virtual void First()
{
_current_index = 0; //让当前 游标 回到位置0
}
virtual void Next()
{
if (_current_index < _ag->getSize())
{
_current_index ++;
}
}
virtual bool IsDone()
{
return (_current_index == _ag->getSize());
}
virtual Object CurrentItem()
{
return _ag->getItem(_current_index);
}
protected:
private:
int _current_index;
Aggregate *_ag;
};
class ConcreteAggregate : public Aggregate
{
public:
ConcreteAggregate()
{
for (int i=0; i<SIZE; i++)
{
object[i] = i + 100;
}
}
virtual MyIterator *CreateIterator()
{
return new ContreteIterator(this); //让迭代器 持有一个 集合的 引用
}
virtual Object getItem(int index)
{
return object[index];
}
virtual int getSize()
{
return SIZE;
}
private:
Object object[SIZE];
};
void main()
{
Aggregate * ag = new ConcreteAggregate;
MyIterator *it = ag->CreateIterator();
for (; !(it->IsDone()); it->Next() )
{
cout << it->CurrentItem() << " ";
}
delete it;
delete ag;
system("pause");
return ;
}