23种设计模式的C++实现、简介、要点

一、工厂模式
简介:在基类中定义一个返回不同子类对象的接口
要点:
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;
}



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值