一、工厂模式
简介:在基类中定义一个返回不同子类对象的接口
要点:
1.在基类中定义一个静态方法,根据传入的值得不同,调用不同子类的构造函数、并返回指向基类的指针
2.将需要子类实现的方法定义为虚方法
3.基类并不会实例化一个对象,而是将对象的实例化延后到子类中进行
4.生成对象时,不显示使用new以及子类构造函数
#include <iostream>
using namespace std;
enum{circle, square, triangle};
class Shape
{
public:
static Shape* getShape(int);
virtual void draw() = 0;//纯虚函数,不必提供定义
virtual ~Shape() { cout<<"Bye shape"<<endl;}
};
class Circle : public Shape
{
public:
void draw() { cout << "circle " << ": draw" << endl; }
~Circle()
{
cout<<"Bye circle \n";
}
};
class Square : public Shape
{
public:
void draw() { cout << "square " << ": draw" << endl; }
~Square()
{
cout<<"Bye Square \n";
}
};
class Triangle : public Shape
{
public:
void draw() { cout << "Triangle " << ": draw" << endl; }
~Triangle()
{
cout<<"Bye Triangle\n ";
}
};
Shape* Shape::getShape(int n)
{
if(n==circle)
return new Circle;
else if(n == square)
return new Square;
else
return new Triangle;
}
int main()
{
Shape* shape[3];
for(int i = 0 ; i <3 ; i++)
{
shape[i]=Shape::getShape(i);
shape[i]->draw();
delete shape[i];
}
return 0;
}
二、抽象工厂
简介:创建工厂的超级工厂
要点:在基类中抽象出工厂的一般方法,以此派生出不同类型的工厂
#include <iostream>
using namespace std;
class Shape {
public:
Shape() { id_ = total_++; }
virtual void draw() = 0;
protected:
int id_;
static int total_;
};
int Shape::total_ = 0;
class Circle : public Shape { public:
void draw() { cout << "circle " << id_ << ": draw" << endl; } };
class Square : public Shape { public:
void draw() { cout << "square " << id_ << ": draw" << endl; } };
class Ellipse : public Shape { public:
void draw() { cout << "ellipse " << id_ << ": draw" << endl; } };
class Rectangle : public Shape { public:
void draw() { cout << "rectangle " << id_ << ": draw" << endl; } };
class Factory { public:
virtual Shape* createCurvedInstance() = 0;
virtual Shape* createStraightInstance() = 0;
static void recycle( Shape* n) { delete n;}
};
class SimpleShapeFactory : public Factory
{
public:
Shape* createCurvedInstance() { return new Circle; }
Shape* createStraightInstance() { return new Square; }
};
class RobustShapeFactory : public Factory
{
public:
Shape* createCurvedInstance() { return new Ellipse; }
Shape* createStraightInstance() { return new Rectangle; }
};
int main() {
Factory* factorySimple = new SimpleShapeFactory;
Factory* factoryRobust = new RobustShapeFactory;
Shape* shapes[3];
shapes[0] = factorySimple->createCurvedInstance();
shapes[1] = factorySimple->createStraightInstance();
shapes[2] = factoryRobust->createCurvedInstance();
for (int i=0; i < 3; i++)
{
shapes[i]->draw();
Factory::recycle(shapes[i]);
}
delete factorySimple;
delete factoryRobust;
return 0;
}
三、建造者模式
简介:将复杂对象的构造过程分解为若干的过程,以便相同的构造过程可以构造出不同表现的对象
要点:
1.将复杂对象分解成若干简单对象
2.将对象不同组件的依赖关系、创建步骤用另外一个类来管理
#include <iostream>
#include <string>
using namespace std;
class Product
{
public:
void MakePartA(const string&name){ partA=name;}
void MakePartB(const string&name){ partB=name;}
void MakePartC(const string&name){ partC=name;}
std::string get()
{
return (partA+" "+partB+" "+partC);
}
private:
std::string partA;
std::string partB;
std::string partC;
};
class Builder
{
public:
virtual void buildPartA()=0;
virtual void buildPartB()=0;
virtual void buildPartC()=0;
virtual ~Builder(){}
Product get()
{
return product;
}
protected:
Product product;
};
class PLAN_X : public Builder
{
public:
void buildPartA(){ product.MakePartA("A-X"); }
void buildPartB(){ product.MakePartB("B-X"); }
void buildPartC(){ product.MakePartC("C-X"); };
};
class PLAN_Y : public Builder
{
public:
void buildPartA(){ product.MakePartA("A-Y"); }
void buildPartB(){ product.MakePartB("B-Y"); }
void buildPartC(){ product.MakePartC("C-Y"); };
};
class Director
{
public:
Director(): plan(){};
void setPlan(Builder* anyPlan)
{
if(plan)
delete plan;
plan=anyPlan;
}
void construct()
{
plan->buildPartA();
plan->buildPartB();
plan->buildPartC();
}
Product getProduct()
{
return plan->get();
}
~Director(){ if(plan) delete plan;}
private:
Builder* plan;
};
int main()
{
Director director;
director.setPlan(new PLAN_X);
director.construct();
Product productA=director.getProduct();
cout<<"The product has been built "<<productA.get()<<endl;
director.setPlan(new PLAN_Y);
director.construct();
Product productB=director.getProduct();
cout<<"The product has been built "<<productB.get()<<endl;
return 0;
}
四、单例模式
简介:确保某个类只有一个实例,并提供全局指针来访问它
要点:
1.声明一个指向这个类的指针私有静态指针
2.声明一个公有的、静态接口来返回这个指针
3.将所有的构造(构造、赋值、拷贝)函数声明为私有的
4.可以被继承,但必须将父类构造函数访问权限声明为保护类型,并将父类声明为子类的友元
#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;
class Logger
{
public:
static Logger* getInstace();
static void setType(const string&anyType){ type=anyType;} //参数列表最好设置为const类型, 否则无法接受字面常量
virtual void show(){ cout<<"My type is "<<type<<endl;}
protected:
Logger(){};
private:
static Logger* instance;
static string type;
};
Logger* Logger::instance=NULL;
string Logger::type="Logger";
class LoggerPlus : public Logger
{
protected:
friend class Logger;
LoggerPlus(){};
private:
static string type;
};
string LoggerPlus::type="LoggerPlus";
Logger* Logger::getInstace()
{
if(!instance)
if(type=="LoggerPlus")
instance=new LoggerPlus();
else
instance=new Logger();
return instance;
}
int main()
{
Logger::getInstace()->show();
Logger::setType("LoggerPlus");
Logger::getInstace()->show();
}
五、适配器模式
简介:将旧类的接口进行转换,以适应新的应用场景
要点:
1.建立一个代理类(adapter)来实现旧类的接口
2.继承旧类,并在子类中使用adapter的方法来替代旧类的接口
#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;
class TwoPortPlug
{
public:
virtual void plugin(){ cout<<"Inserted to two holes socket\n";}
};
class Adapter
{
public:
void three2two() { cout<<" Ajusted three plugs to two plugs\n";}
};
class ThreePortPlug : public TwoPortPlug
{
public:
ThreePortPlug(): adapter(){}
void plugin() override { adapter->three2two();}
~ThreePortPlug(){ delete adapter;}
private:
Adapter* adapter;
};
int main()
{
ThreePortPlug a;
a.plugin();
}
六、桥接模式
简介:将抽象与实现分离,使二者可以独立变化
要点:
1.抽象与实现表征的是一个类多个维度的变化
2.实现依赖于抽象
e.g.
不同类型的数据库:MySQL、SQLite,它们是数据库的抽象,不同开发商的数据库会有区别;然后操作数据库的GUI应用,这是实现,可能也会有不同的形式
#include <iostream>
#include <string>
using namespace std;
class SQL
{
public:
virtual void showVersion()=0;
virtual ~SQL(){ }
};
class MySQL: public SQL
{
public:
MySQL() : version( "MySQL") { }
void showVersion(){ cout<<version<<endl;}
private:
string version;
};
class SQLite: public SQL
{
public:
SQLite() : version( "SQLite") { }
void showVersion(){ cout<<version<<endl;}
private:
string version;
};
class GUI
{
public:
GUI( SQL *database):db(database){}
~GUI(){delete db;}
void showDB(){db->showVersion();}
private:
SQL* db;
};
int main()
{
GUI* one = new GUI(new MySQL);
one->showDB();
GUI* two = new GUI(new SQLite);
two->showDB();
delete one;
delete two;
}
七、组合模式
简介:包含了容器的容器,一个对象里面包含了以树形结构组织的一系列相似的对象
要点:
1.创建容器和被包含的容器的通用接口
2.定义管理子对象的容器
3.定义操作子对象的方法如add、get、remove
e.g.
假设电脑足够强劲,在一台虚拟机里又开了若干台虚拟机
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Machine
{
public:
Machine( int ID = 0) : id(ID){ }
virtual ~Machine(){ }
void powerOn() { cout<<id<<" powered on"<<endl;}
void powerOff() { cout<<id<<" powered off "<<endl;}
virtual void add(Machine*) { } ;
virtual void remove(const int ) { };
private:
int id;
};
class MainMachine : public Machine
{
public:
MainMachine(int ID = 0) :Machine(ID) {}
void add( Machine* child) override
{
list.push_back(child);
child->powerOn();
}
Machine* getChillren(int index)
{
return list.at(index);
}
void remove(const int index) override
{
Machine* child=getChillren(index);
child->powerOff();
list.erase(list.begin()+index);
delete child;
}
private:
vector<Machine*> list;
};
int main()
{
MainMachine machine;
for(int i = 0 ; i <10 ; i++)
machine.add(new Machine(i));
machine.remove(5);
machine.powerOff();
return 0;
}
八、装饰器模式
简介:动态地给对象添加新的功能
要点:
1.与继承的区别在于,装饰器可以动态地给一个已经实例化的对象添加新功能
2.先将对象打包,再对包装进行装饰
3.包装在继承了对象的实现和接口的基础上,保留了指向对象的指针作为私有成员,并使用这个指针来调用属于对象的方法(不能使用作用域Conponet::的方式)
4.关键在于虚函数和类作用域:
对于被声明为虚函数类型的函数,指向基类的指针将会调用子类版本;下一次修饰,上一次修饰后的加入的修饰内容在wrapper类的中仍然是可见的
#include <iostream>
#include <string>
using namespace std;
class Conponent
{
public:
virtual void operation()
{
cout<<"Conponent implented"<<endl;
}
virtual ~Conponent(){ }
};
class Wrapper : public Conponent
{
public:
Wrapper( Conponent* c):conponent(c){}
void operation()
{
conponent->operation();//不能使用Conponent::operation()
}
private:
Conponent* conponent;
};
class DecoratorA : public Wrapper
{
public:
DecoratorA(Conponent* c): Wrapper(c){}
void operation()
{
Wrapper::operation();
cout<<"Decorated with A"<<endl;
}
};
class DecoratorB : public Wrapper
{
public:
DecoratorB(Conponent* c): Wrapper(c){}
void operation()
{
Wrapper::operation();
cout<<"Decorated with B"<<endl;
}
};
int main()
{
Wrapper* x = new Wrapper(new Conponent);
DecoratorA* xA = new DecoratorA(x);
DecoratorB* xAB = new DecoratorB(xA);
Conponent* xab = xAB;
xab->operation();
return 0;
}
九、外观模式
简介:为子系统的一组接口提供一个统一、更易于使用的接口
要点:
1.外观代理了客户向子系统的请求
2.子系统对客户不可见
3.外观对子系统不可见
e.g.
以前的票务系统买张票要打车、排队、缴费、取票,为方便可以直接找人代理
#include <iostream>
#include <string>
using namespace std;
class TicketSystem
{
public:
void takeBus(){}
void waitForYourTurn(){}
void pay(){}
void getTicket(){cout<<"Ticket got"<<endl;}
};
class HuangNiu
{
public:
HuangNiu():step(){}
void call()
{
step->takeBus();
step->waitForYourTurn();
step->pay();
step->getTicket();
}
private:
TicketSystem* step;
};
int main()
{
HuangNiu a;
a.call();
return 0;
}
十、享元模式
简介:以重用已有对象的方式,来减少创建对象的数量
要点:
1.新对象以工厂模式获得
2.给每个对象分配唯一标识符,如果请求的对象与既有对象的标识符相同,则工厂返回已有对象
e.g.
陪三秒钟记忆的女朋友去购物,管理购物清单,确保购物车没有重复的商品
#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct ShopItem
{
string name;
int order;
};
class ShopItemFactory
{
public:
ShopItem* getShopItem(const string&item)
{
for(auto i : shopList)
if(item==i->name)
{
cout<<"There is already an " <<item<<endl;
return i;
}
ShopItem* newItem = new ShopItem{item,int(shopList.size())};
shopList.push_back(newItem);
cout<<"New item " <<item<<" added"<<endl;
return newItem;
}
~ShopItemFactory()
{
for(auto i : shopList) delete i;
shopList.clear();
}
private:
vector<ShopItem*> shopList;
};
int main()
{
ShopItemFactory* factory = new ShopItemFactory;
factory->getShopItem("car");
factory->getShopItem("cat");
factory->getShopItem("car");
delete factory;
return 0;
}
十一、代理模式
简介:为对象创建一个新对象,以提供对原对象更灵活的访问
要点:在新对象中存放指向原对象的指针
#include<iostream>
using namespace std;
class RealSubject
{
public:
virtual void execute(){cout<<"Original excuted"<<endl;}
virtual ~RealSubject(){}
};
class ProxySubject:public RealSubject
{
public:
ProxySubject() :ptr(new RealSubject){}
~ProxySubject(){delete ptr;}
void execute() { cout<<"Proxy excuted"<<endl;}
RealSubject* operator ->()
{
return ptr;
}
private:
RealSubject* ptr;
};
int main()
{
ProxySubject a;
a.execute();
a->execute();
}
十二、责任链模式
简介:来自发送端的请求会一直沿接收链传递下去,直到请求被接收链上的某个节点处理
要点:
1.在基类中声明一个指向接收链上下一个节点的的指针
2.如果需要传递请求,则调用代理了下一个节点的基类方法
e.g.
某人问你借钱
#include <iostream>
using namespace std;
class Method
{
public:
Method():method(NULL){}
virtual void Borrow(int number)
{
if(method)
method->Borrow(number);
else
cout<<"I don't know him"<<endl;
}
void setMethod(Method* m){method=m;}
private:
Method* method;
};
class Cash :public Method
{
public:
void Borrow(int number)
{
if(100 > number)
cout<<"Borrow him "<<number<<" in cash"<<endl;
else
Method::Borrow(number);
}
};
class AliPay :public Method
{
public:
void Borrow(int number)
{
if(1000 > number)
cout<<"Borrow him "<<number<<" in aliPay"<<endl;
else
Method::Borrow(number);
}
};
int main()
{
Cash* cash = new Cash;
AliPay* alipay = new AliPay;
cash->setMethod(alipay);
cash->Borrow(20);
cash->Borrow(200);
cash->Borrow(2000);
}
十三、命令模式
简介:将每项操作分别打包成一个对象
要点:
1.面向对象编程中执行一个请求无非就是实例化一个类的对象,再通过对象去调用类方法
2.现在声明一个抽象的命令类,在命令类中包含了指向另一个类对象的指针,以及其中的一个类方法
3.每一个请求都对应命令类下的一个实例,通过往命令类的构造函数中传入不同的类及其中的一个类方法,来达到创建不同命令的目的
4.构建另一个类来专门响应不同的请求及相应的命令
把请求看作一件工作,老板会把请求分配给工人去执行,并指定工人去做什么
#include <iostream>
#include <string>
using namespace std;
class Worker
{
public:
void draw(){cout<<"drawing"<<endl; }
void write(){cout<<"writing"<<endl; }
void read(){cout<<"reading"<<endl; }
};
typedef void (Worker::*callback)();
class Command
{
public:
virtual void execute()=0;
};
class Job : public Command
{
public:
Job( Worker* a ,callback skill ):icu(a) ,requirement(skill) { }
void execute(){ (icu->*requirement)();}
private:
Worker* icu;
callback requirement ;
};
class Boss
{
public:
void handJob(Command* cmd){ cmd->execute(); }
};
int main()
{
Boss Alex;
Worker* Lily = new Worker;
Job* job = new Job( Lily,&Worker::draw);
Alex.handJob(job);
}
十四、解释器模式
简介:给既定的语言,按其语法定义相应的操作并使用解释器来执行其语句
要点:
定义一个接口来解释一定的上下文
#include <iostream>
#include <cstring>
#include <map>
#include <vector>
#include <string>
using namespace std;
class Interpretion
{
public:
Interpretion( int scale ,const char* bass ):m_scale(scale),m_bass(bass)
{
trans.insert(pair<char,int>('0',0));
trans.insert(pair<char,int>('1',1));
trans.insert(pair<char,int>('2',2));
trans.insert(pair<char,int>('3',3));
trans.insert(pair<char,int>('4',4));
trans.insert(pair<char,int>('5',5));
trans.insert(pair<char,int>('6',6));
trans.insert(pair<char,int>('7',7));
trans.insert(pair<char,int>('8',8));
trans.insert(pair<char,int>('9',9));
trans.insert(pair<char,int>('A',10));
trans.insert(pair<char,int>('B',11));
trans.insert(pair<char,int>('C',12));
trans.insert(pair<char,int>('D',13));
trans.insert(pair<char,int>('E',14));
trans.insert(pair<char,int>('F',15));
}
int translate(char a)
{
return trans.find(a)->second;
}
virtual void interpret(char* )=0;
virtual ~Interpretion(){ }
int getWeight(int k)
{
int weigt=1;
for(int i = 0 ;i <k - 1 ;i++ )
weigt*=m_scale;
return weigt;
}
char getExpress(int k)
{
return m_bass[k];
}
private:
map<char,int> trans;
int m_scale;
const char* m_bass;
};
class HexToDec :public Interpretion
{
public:
HexToDec( ) :Interpretion(16,"")
{
}
void interpret(char* input )
{
int size=strlen(input);
int result=0;
for(int i = 0 ; i < size; i++ )
{
result+=translate(input[i])*getWeight(size-i);
}
cout<<"Hex "<<input<<" to oct is "<<result<<endl;
}
};
class DecToHex :public Interpretion
{
public:
DecToHex() : Interpretion(10,"0123456789ABCDEF" ) { }
void interpret(char* input )
{
int result = atoi(input);
int temp=16;
cout<<"Dec "<< input<<" to Hex is ";
vector<char> prints;
while (true)
{
if(result<16)
prints.push_back(getExpress(result));
else
prints.push_back(getExpress(result%16));
if(result /temp==0) break;
result/=16;
}
for(int i = 0 ; i < prints.size(); i ++)
cout<<prints.at(prints.size() -i -1);
}
};
class Contex
{
public:
Contex():input(NULL){ }
void getInput()
{
if(! input)
{
delete input;
input=NULL;
}
input = new char[1000];
memset(input,'\0',1000);
cin>>input;
}
char* getValue() { return input;}
private:
HexToDec* HtoD;
DecToHex* DtoH;
char* input;
};
int main()
{
Contex* cont = new Contex();
cout<<"Enter a hex :\n";
cont->getInput();
HexToDec* hexTransfer = new HexToDec();
hexTransfer->interpret(cont->getValue());
DecToHex* octTransfer = new DecToHex();
cout<<"Enter a Dec:\n";
cont->getInput();
octTransfer->interpret(cont->getValue());
delete cont;
delete hexTransfer;
delete octTransfer;
}
十五、迭代器模式
简介:提供一种在不暴露内部表达形式的情况下,顺序访问数据集合中的元素的方法
要点:
1.在集合类中定义一个创建迭代器的create_iterator()方法,并给予迭代器类特定的访问权限
2.创建一个可以遍历集合类元素的迭代器类
3.客户端使用集合类的对象来创建迭代器类的对象
4.客户端使用按特定的协议、可以获得集合类对象的第一个元素、当前元素、下一个元素、元素总数
#include <iostream>
#include <vector>
using namespace std;
class Literator;
class List
{
public:
friend class Literator;
List(int size ) :m_size(size) ,index(0) { list=new int[ m_size]{0}; }
~List(){ delete list;}
int currentItem() { return list[index]; }
Literator* createLiterator();
private:
int* list;
int m_size;
int index;
};
class Literator
{
public:
Literator(List* object):myList(object) { }
void first() { myList->index=0;}
int current() { return myList->currentItem();}
void next() { myList->index++;}
bool isDone(){ return myList->index < myList->m_size; }
~Literator() { cout<<"Bye~"; }
private:
List* myList;
};
Literator* List::createLiterator()
{
return new Literator (this);
}
int main(void)
{
List* test = new List(5);
Literator* literator= test->createLiterator();
for(literator->first(); literator->isDone(); literator->next())
cout<<literator->current();
delete test;
delete literator;
return 0;
}
十六、中介模式
简介:定义一个来管理复数对象的交互,使对象之间不需要显示调用彼此
要点:
1.抽象一个新的类来管理对象之间的交互
2.对象都仅与这个新的类的实例进行交互
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Customer
{
public:
Customer(const string& name) :m_name(name) { }
void speak(const string&word){ cout<<m_name<<" said "<<word<<endl; }
void listen(const string&word) { cout<<m_name<<" heard "<<word <<endl;}
private:
string m_name;
};
class Mediator
{
public:
~Mediator()
{
for ( auto i : namelist)
delete i;
}
void send(int id, const string&msg)
{
if( id < namelist.size())
{
namelist[id]->speak(msg);
for(int i = 0 ; i <namelist.size(); i++)
if(id != i)
namelist[i]->listen(msg);
}
}
void add( Customer* cus){ namelist.push_back(cus); }
private:
vector<Customer*> namelist;
};
int main()
{
Mediator* mediator = new Mediator;
Customer* A = new Customer("Alex");
Customer* B = new Customer("Alice");
Customer* C = new Customer("Mike");
mediator->add(A);
mediator->add(B);
mediator->add(C);
mediator->send(0,"Hello");
}
十七、备忘录模式
简介:在不破坏封装性的前提下,保存对象的状态,以便撤销操作或回滚至原状态
要点:
1.区分并创建原件和管理员类
2.创建一个备份类,将原件声明为友元
3.由原件创建备份,并在备份中保存自己的状态
4.由管理员确定何时保存、回滚原件状态
5.从备份从恢复原件的状态
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Memento
{
public:
friend class Original;
Memento ( int s ) :memState(s){ }
int getState(){return memState;}
private:
int memState;
};
class Original
{
public:
Original(int state=0) : m_state(state) { }
void setState(int s){ m_state = s;}
void restore( Memento* m ) { m_state = m->getState();}
void getState() { cout<<"Current state is "<<m_state<<endl;}
Memento* CreateMemento() { return new Memento(m_state); }
private:
int m_state;
};
class CareTaker
{
public:
CareTaker( Original* const o) :orignal(o) { }
~CareTaker(){ for(auto i : history) delete i; }
void save() { history.push_back(orignal->CreateMemento()); }
void undo()
{
if(! history.empty())
{
Memento* m = history.back();
orignal->setState(m->getState());
history.pop_back();
delete m;
}
}
private:
Original* orignal;
vector<Memento*> history;
};
int main()
{
Original* originator = new Original;
CareTaker* takecare = new CareTaker (originator);
originator->setState(100);
takecare->save();
originator->getState();
originator->setState(50);
takecare->save();
originator->getState();
originator->setState(5);
takecare->undo();
originator->getState();
}
十八、观察者模式
简介:观察者建立了一对多的依赖关系,在一个对象的状态发生改变时,其它对象也自动更新状态
要点:
1.将不变或者不存在依赖关系的部分抽象成主体
2.将可变或存在依赖关系的部分抽象成观察者
3.主体仅仅与观察者耦合
4…用户决定观察者的数量和类型
5.将观察者注册至主体
6.主体状态发生改变的同时,将事件广播至所有注册了的观察者
e.g.火警报警器响起时,打开灭火器、播放广播、疏散人流
#include <iostream>
#include <vector>
using namespace std;
class AlarmListener
{
public:
virtual ~AlarmListener(){ }
virtual void takeAction()=0;
};
class FireFigter : public AlarmListener
{
public:
void takeAction() { cout<<"Firefigher coming "<<endl;}
};
class Radio : public AlarmListener
{
public:
void takeAction() { cout<<"Broading message "<<endl;}
};
class Alarm
{
public:
~Alarm() { for(auto i : list) delete i;}
void fireDetected( ){ for(auto i : list) i->takeAction(); }
void attach(AlarmListener* m) { list.push_back(m); }
private:
vector<AlarmListener*> list;
};
int main()
{
Alarm* alarm = new Alarm;
alarm->attach(new FireFigter);
alarm->attach(new Radio);
alarm->fireDetected();
}
十九、状态模式
简介:允许对象在不同状态下,表现出不同的行为
要点:
1.创建一个所有状态的基类,并尽可能定义更多默认的行为
2.为每个状态创建一个子类,并重写基类方法
3.新建一个包含了基类的类,并提供修改具体使用哪个子类的方法
#include <iostream>
#include <vector>
using namespace std;
class State
{
public:
virtual void handRequest()=0;
virtual ~State() { }
};
class StateA :public State
{
public:
void handRequest() { cout<<"State A "<<endl; }
};
class StateB :public State
{
public:
void handRequest() { cout<<"State B "<<endl; }
};
class Machine
{
public:
Machine():currentState(NULL) {}
~Machine(){ if(currentState) delete currentState;}
void setState(State* s)
{
if(currentState)
delete currentState;
currentState=s;
}
void request(){ if(currentState) currentState->handRequest();}
private:
State* currentState;
};
int main()
{
Machine* machine = new Machine;
machine->request();
machine->setState(new StateA);
machine->request();
machine->setState(new StateB);
machine->request();
}
二十、策略模式
简介:和上面的状态模式的区别就是,不需要提供改变当前状态的接口
要点:
1.用户可以决定使用哪个算法
2.不同算法使用相同的接口
#include <iostream>
#include <vector>
using namespace std;
class Strategy
{
public:
virtual void handwork()=0;
virtual ~Strategy() { }
};
class StrategyA :public Strategy
{
public:
void handwork() { cout<<"Strategy A "<<endl; }
};
class StrategyB :public Strategy
{
public:
void handwork() { cout<<"Strategy B "<<endl; }
};
class Machine
{
public:
Machine( Strategy* s):currentStrategy(s) {}
~Machine(){ delete currentStrategy;}
void work(){ currentStrategy->handwork();}
private:
Strategy* currentStrategy;
};
int main()
{
Machine* machine = new Machine(new StrategyA);
machine->work();
}
二十一、模板模式
简介:在基类中定义算法的框架,子类重写基类方法来实现具体的、有差异的步骤
要点:
1.在基类中实现标准的部分
2.子类来实现差异的部分
#include <iostream>
#include <vector>
using namespace std;
class Operation
{
public:
virtual ~Operation() { }
void start() { cout<<"Starting ..."<<endl;}
virtual void stepA()=0;
virtual void stepB()=0;
void end() { cout<<"Ended..\n";}
void execute()
{
start();
stepA();
stepB();
end();
}
};
class OperationOne : public Operation
{
public:
void stepA() override{ cout<<"One's A"<<endl;}
void stepB() override{ cout<<"One's B"<<endl;}
};
class OperationTwo : public Operation
{
public:
void stepA() override{ cout<<"Two's A"<<endl;}
void stepB() override{ cout<<"Two's B"<<endl;}
};
int main(int argc, char *argv[])
{
OperationOne one;
OperationTwo two;
one.execute();
two.execute();
return 0;
}