C++设计模式

来源:互联网 发布:数据库系统全书 编辑:程序博客网 时间:2024/06/08 04:57

注:文中的代码都是经过调试运行的,大部分并未给出头文件而已

一、模式的分类

1、 创建型(Creational)

单件模式(Singleton)

简单工厂模式(Factory)

工厂方法模式(Factory Method)

抽象工厂模式(Abstract Factory)

构建器模式(Builder)

原型模式(Prototype)

2、 结构型(Structural)

代理模式(Proxy)

适配器模式(Adapter Class/Object)

桥接模式(Bridge)

组合模式(Composite)

装饰模式(Decorator)

外观模式(Facade)

享元模式(Flyweight)

3、 行为型(Behavioral)

命令模式(Command)

模板方法模式(Template Method)

状态模式(State)

迭代器模式(Iterator)

中介者模式(Mediator)

解释器模式(Interpreter)

策略模式(Strategy)

职责链模式(Chain of Respinsibility)

观察者模式(Observer)

多派遣模式(Multiple Dispatching)

访问者模式(Vistor)

备忘录模式(Memonto)

二、详解

1、单件模式(Singleton)

作用:保证只有一个类的实例,防止客户程序员拥有控制其对象生存期的权利,

并提供一个可以访问它的全局访问点

       这样的类不允许创建对象,拷贝构造等相关操作,可以使用get_instance()获取引用,也可以使用相关成员函数获取修改相关数据,这里不用指针是为了防止用户意外删除。

class Signalton{private:    static Signalton _signal;    Signalton();    Signalton(Signalton&);    Signalton& operator=(Signalton&);    //something should be insert into here,just like the data;public:    static Signalton& get_instance()    {       return _signal;    }     void operate_data()    {       //something should be insert into here    }     void get_data()    {       //something should be insert into here    }}; Signalton Signalton::_signal;

单例模式还有一种变种只有当用户调用get_instance()函数时才会进行创建和初始化

class Signalton{private:    int _value;Signalton();    Signalton(int data) :_value(data){}    Signalton& operator=(Signalton&);    Signalton(const Signalton&);public:    static Signalton& get_instance()    {       static Signalton _signal(13);       return _signal;    }     int get_data()    {       return _value;    }     void set_data(int data)    {       _value = data;    }};

2、简单工厂模式(Factory)

主要用于创建对象。新添加类时,不会影响以前的系统代码。核心思想是用一个工厂来根据输入的条件产生不同的类,然后根据不同类的virtual函数得到不同的结果。适用于不同的状况创建不同的类,缺点是客户端必须知道基类和工厂类,耦合性差。

class data{public:    int _value;public:    data(int tmp) :_value(tmp){}    virtual int operate()    {       return 0;    }}; class data_squre :public data{public:    data_squre(int tmp) :data(tmp){}    virtual int operate()    {       return data::_value * data::_value;    }}; class data_add :public data{public:    data_add(int tmp) :data(tmp){}    virtual int operate()    {       return data::_value + data::_value;    }}; class data_div :public data{public:    data_div(int tmp) :data(tmp){}    virtual int operate()    {       return data::_value / data::_value;    }}; class factory{public:    static data* create(int index, int value);}; data* factory::create(int index, int value){    data* dt = nullptr;    switch (index)    {    case 0:dt = new data_add(value); break;    case 1:dt = new data_div(value); break;    case 2:dt = new data_squre(value); break;    default:       std::cout << "创建失败\n";    }     return dt;}

3、工厂方法模式(Factory Method) 

  工厂方法模式和见到那工厂的区别是,简单工厂创建的不同类由同一个工厂创建,工厂方法创建的类根据不同的情况选择不同的工厂创建。

  修正了简单工厂模式中不遵守开放-封闭原则。工厂方法模式把选择判断移到了客户端去实现,如果想添加新功能就不用修改原来的类,直接修改客户端即可。


class data{public:    int _value;public:    data(int tmp) :_value(tmp){}    virtual int operate()    {       return 0;    }}; class data_squre :public data{public:    data_squre(int tmp) :data(tmp){}    virtual int operate()    {       return data::_value * data::_value;    }}; class data_add :public data{public:    data_add(int tmp) :data(tmp){}    virtual int operate()    {       return data::_value + data::_value;    }}; class data_div :public data{public:    data_div(int tmp) :data(tmp){}    virtual int operate()    {       return data::_value / data::_value;    }}; class data_factory{public:    virtual data* create(int value)    {       return new data(value);    }}; class data_add_factory:public data_factory{public:    virtual data* create(int value)    {       return new data_add(value);    }}; class data_div_factory :public data_factory{public:    virtual data* create(int value)    {       return new data_div(value);    }}; class data_squre_factory :public data_factory{public:    virtual data* create(int value)    {       return new data_squre(value);    }};

4、抽象工厂模式(Abstract Factory) 

定义了一个创建一系列相关或相互依赖的接口,而无需指定它们的具体类。


class user{public:    virtual void get_user() = 0;    virtual void add_user() = 0;}; class c_user :public user{public:    virtual void get_user()    {       std::cout << "获取C程序员\n";    }     virtual void add_user()    {       std::cout << "添加C程序员\n";    }}; class php_user :public user{public:    virtual void get_user()    {       std::cout << "获取PHP程序员\n";    }     virtual void add_user()    {       std::cout << "添加PHP程序员\n";    }}; class java_user :public user{public:    virtual void get_user()    {       std::cout << "获取java程序员\n";    }     virtual void add_user()    {       std::cout << "添加java程序员\n";    }}; //部门class part{public:    virtual void get_part() = 0;    virtual void add_part() = 0;}; class c_part:public part{public:    virtual void get_part()    {       std::cout << "获取C部门\n";    }     virtual void add_part()    {       std::cout << "添加C部门\n";    }}; class php_part :public part{public:    virtual void get_part()    {       std::cout << "获取PHP部门\n";    }     virtual void add_part()    {       std::cout << "添加PHP部门\n";    }}; class java_part :public part{public:    virtual void get_part()    {       std::cout << "获取java部门\n";    }     virtual void add_part()    {       std::cout << "添加java部门\n";    }}; class factory{public:    virtual user* create_user() = 0;    virtual part* create_part() = 0;}; class c_factory :public factory{public:    virtual user* create_user()    {       return new c_user;    }     virtual part* create_part()    {       return new c_part;    }}; class php_factory :public factory{public:    virtual user* create_user()    {       return new php_user;    }     virtual part* create_part()    {       return new php_part;    }}; class java_factory :public factory{public:    virtual user* create_user()    {       return new java_user;    }     virtual part* create_part()    {       return new java_part;    }};

5、构建器模式(Builder) 

       将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。 

  

class car{public:    virtual void create_wheel() = 0;    virtual void create_window() = 0;    virtual void create_chair() = 0;    virtual void create_engine() = 0;}; class truck :public car{public:    virtual void create_wheel()    {       std::cout << "卡车轮子\n";    }     virtual void create_window()    {       std::cout << "卡车窗户\n";    }     virtual void create_chair()    {       std::cout << "卡车座椅\n";    }     virtual void create_engine()    {       std::cout << "卡车发动机\n";    }}; class couepe :public car{public:    virtual void create_wheel()    {       std::cout << "小轿车轮子\n";    }     virtual void create_window()    {       std::cout << "小轿车窗户\n";    }     virtual void create_chair()    {       std::cout << "小轿车座椅\n";    }     virtual void create_engine()    {       std::cout << "小轿车发动机\n";    }}; class builder{private:    car* _car;public:    builder(car* tmp) :_car(tmp){}    void create()    {       _car->create_chair();       _car->create_engine();       _car->create_wheel();       _car->create_window();    }};

6、原型模式(Prototype) 

从一个对象再创建另外一个可定制的对象,而无需知道任何创建的细节。并能提高创建的性能。


class property{    std::string _name;public:    property(std::string tmp) : _name(tmp){}    property(){ _name = ""; }    void show()    {       std::cout << _name.c_str() << std::endl;    }    virtual property* clone() = 0;}; class property_rst :public property{public:    property_rst(std::string tmp) :property(tmp){}    property_rst(){}    virtual property* clone(void)    {       property_rst* ptr = new property_rst;       *ptr = *this;       return ptr;    }}; class property_snd :public property{public:    property_snd(std::string tmp) :property(tmp){}    property_snd(){}    virtual property* clone(void)    {       property_snd* ptr = new property_snd;       *ptr = *this;       return ptr;    }};

7、代理模式(Proxy)

代理模式一般用途如下:

远程代理(Remote Proxy):可以隐藏一个对象在不同地址空间的事实

虚拟代理(Virtual Proxy):通过代理来存放需要很长时间实例化的对象,利用惰性初始化实现

安全代理(保护代理ProtectionProxy):用来控制真是对象的访问权限

智能引用(Smart Reference):当调用真是对象时,代理处理另外一件事


class interface{public:    virtual void operate() = 0;}; class real_class :public interface{public:    virtual void operate()    {       std::cout << "真实请求\n";    }}; class proxy_class :public interface{private:    real_class* _real_class;public:    virtual void operate()    {       _real_class = new real_class;       _real_class->operate();       delete _real_class;    }};

8、适配器模式(Adapter Class/Object) 

当用户所希望的接口系统无法提供时可以用适配器模式将接口转换为另一个接口例如当一类不支持迭代器时,利用类嵌套为目标类添加相应的支持


//不具备做高中题目的能力class target{public:    virtual void operate()    {       std::cout << "做小学题目\n";    }}; class Sper{public:    void operate()    {       std::cout << "做高中题目\n";    }}; //既可以做小学题目又可以做高中题目class user:public target{private:    Sper* _sp;public:    void operate()    {       _sp->operate();       target::operate();    }    user()    {       if (_sp)       {           delete _sp;       }        _sp = new Sper;    }};

 9、桥接模式(Bridge) 

将抽象部分与实现部分分离,使它们可以独立变化。

不是让抽象基类与具体类分离,而是现实系统可能有多角度分类,每一种分类都有可能变化,那么把这种多角度分离出来让它们独立变化,减少它们之间的耦合性,即如果继承不能实现“开放-封闭原则”的话,就应该考虑用桥接模式。


class pc_app{public:    virtual void run(void) = 0;}; class vs_app :public pc_app{public:    virtual void run(void)    {       std::cout << "vs2013运行\n";    }}; class LOL_app :public pc_app{public:    virtual void run(void)    {       std::cout << "LOL正在运行\n";    }}; class computer{private:    pc_app* _app;public:    void set_app(pc_app* app)    {       _app = app;    }     virtual void run(void)    {       _app->run();    }}; class dell :public computer{};class acer :public computer{};

10、组合模式(Composite) 

  部分整体一致对待


class root{public:    std::string _name;public:    root(std::string tmp) :_name(tmp){}    virtual void add_root(root*) = 0;    virtual void show(int depth = 0) = 0;}; class leaf :public root{public:    leaf(std::string tmp) :root(tmp){}    virtual void add_root(root* tmp)    {       std::cout << "叶子无法添加组件\n";    }    virtual void show(int depth = 0)    {       std::string tmp = "";       for (int i = 0; i < depth; i++)       {           tmp += "-";       }        tmp += _name;       std::cout << tmp.c_str();    }}; class root_tmp:public root{private:    std::vector<root*> _root;public:    root_tmp(std::string tmp) :root(tmp){}    void add_root(root* tmp)    {       _root.push_back(tmp);    }     void show(int depth = 0)    {       std::string tmp = "";       for (int i = 0; i < depth; i++)       {           tmp += "-";       }        tmp += _name;       std::cout << tmp.c_str();       std::vector<root*>::iterator it = _root.begin();       for (; it != _root.end(); it++)       {           (*it)->show(depth += 2);       }    }};

11、装饰模式(Decorator)

动态地给一个对象添加一些额外的职责(不重要的功能,只是偶然一次要执行),就增加功能来说,装饰模式比生成子类更为灵活。建造过程不稳定,按正确的顺序串联起来进行控制。

在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。处理那些可以撤消的职责。当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。


class preson{private:    std::string _name;public:    preson(std::string tmp) :_name(tmp){}    preson(){}    virtual void show()    {       std::cout << "姓名是"<<_name.c_str();    }}; class decorator:public preson{protected:    preson* _person;public:    void decorate(preson* tmp)    {       _person = tmp;    }    virtual void show()    {       _person->show();    }}; class hat :public decorator{public:    void show()    {       std::cout << "hat !";       decorator::show();    }}; class shirt :public decorator{public:    void show()    {       std::cout << "shirt !";       decorator::show();    }};

12、外观模式(Facade) 

为子系统的一组接口提供一个一致的界面。


class method_rst{public:    void run()    {       std::cout << "first method\n";    }}; class method_snd{public:    void run()    {       std::cout << "second method\n";    }}; class method_thd{public:    void run()    {       std::cout << "third method\n";    }}; class facade{    method_rst* _th_rst;    method_snd* _th_snd;    method_thd* _th_thd;public:    facade()    {       _th_rst = new method_rst;       _th_snd = new method_snd;       _th_thd = new method_thd;    }    ~facade()    {       delete _th_rst;       delete _th_snd;       delete _th_thd;    }    void run()    {       _th_rst->run();       _th_snd->run();       _th_thd->run();    }};

13、享元模式(Flyweight) 

 运用共享技术有效地支持大量细粒度的对象(对于C++来说就是共用一个内存块啦,对象指针指向同一个地方)。

         如果一个应用程序使用了大量的对象,而这些对象造成了很大的存储开销就应该考虑使用。还有就是对象的大多数状态可以外部状态,如果删除对象的外部状态,那么可以用较少的共享对象取代多组对象,此时可以考虑使用享元。


class web{public:    virtual void use() = 0;}; class share_web :public web{private:    std::string _name;public:    share_web(std::string tmp) :_name(tmp)    {}     virtual void use()    {       std::cout << "共享网站\n";    }}; class unshare_web :public web{private:    std::string _name;public:    unshare_web(std::string tmp) :_name(tmp)    {}     virtual void use()    {       std::cout << "不共享网站\n";    }}; //网站工厂class web_fatory{private:    std::vector<web*> _web;public:    web_fatory()    {       _web.push_back(new share_web("share web"));    }    web* getweb()    {       std::vector<web*>::iterator it = _web.begin();       return *it;    }};

14、命令模式(Command)

命令模式是将操作的对象和操作的命令分离,可以将命令装载入队列,执行与否可由操作者决定,而且并不影响其他类的新类,可用于撤销操作 可以将命令模式假想为顾客点餐的过程,客户端是客户,命令接受者是服务员,命令可以是不同的菜。客户可以选择点那份菜,(请求命令)服务员可以选择通知命令的与否命令由命令类派生可以列入队列等待执行,可以想象为一个厨师同时做不同的菜

      

class COOK{public:    void fish()    {       std::cout << "水煮鱼\n";    }    void tofu()    {       std::cout << "千叶豆腐\n";    }    void beef()    {       std::cout << "牛肉\n";    }}; class Command{protected:    COOK* cooker;public:    //可以修改厨师参数    Command(COOK* tmp)    {       tmp = cooker;    }     virtual void operate() = 0;}; class fish :public Command{public:    fish(COOK* tmp) :Command(tmp){}    virtual void operate()    {       cooker->fish();    }}; class beef :public Command{public:    beef(COOK* tmp) :Command(tmp){}    virtual void operate()    {       cooker->beef();    }}; class tofu :public Command{public:    tofu(COOK* tmp) :Command(tmp){}    virtual void operate()    {       cooker->tofu();    }}; class waiter{protected:    std::vector<Command*> _list;public:    //点菜    void order(Command* tmp)    {       _list.push_back(tmp);       std::cout << "点菜成功\n";    }     void run()    {       std::vector<Command*>::iterator it = _list.begin();       while (it != _list.end())       {           (*it)->operate();           it++;       }    }};

15、模板方法模式(Template Method) 

函数的统一执行交由父类管理,而接口的具体实现有子类实现


class template_cls{public:    virtual void fun_rst() = 0;    virtual void fun_snd() = 0;    void run()    {       fun_rst();       fun_snd();    }}; class cls_rst :public template_cls{public:    virtual void fun_rst()    {       std::cout << "我是第一个孩子\n";    }    virtual void fun_snd()    {       std::cout << "我的父亲是template_cls\n";    }};

16、状态模式(State) 

允许类的执行操作取决于类的状态,可以想象一个人一天中有不同的规划,早上,中午,下午。这个人所做的事情可以根据时间点的变化而变化。


class work;class State{public:    virtual void do_sth(work*) = 0;}; class work{private:    State* _state;public:    double hour;public:    work()    {       _state = nullptr;    }     void set_state(State* tmp)    {       if (_state)       {           delete _state;           _state = nullptr;       }        _state = tmp;    }     void run()    {       _state->do_sth(this);    } }; class night :public State{public:    virtual void do_sth(work* w)    {       std::cout << "睡觉!\n";    }}; class mor :public State{public:    virtual void do_sth(work* w)    {       std::cout << "起床!\n";    }}; class noon :public State{public:    virtual void do_sth(work* w)    {       std::cout << "上班!\n";    }};

17、迭代器模式(Iterator) 

提供一种方法顺序访问一个聚敛对象的各个元素,而又不暴露该对象的内部表示。为遍历不同的聚集结构提供如开始,下一个,是否结束,当前一项等统一接口。


18、中介者模式(Mediator)

用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显示的相互引用,从而降低耦合;而且可以独立地改变它们之间的交互。

可以把中介类想像成一个中介公司


class man;//中介类class mediator{public:    virtual void send(std::string msg, man* tmp) = 0;}; //操作对象class man{protected:    mediator* _mediator;public:    man(mediator* tmp) :_mediator(tmp){}}; class man_rst :public man{public:    man_rst(mediator* tmp) :man(tmp){}    void send(std::string msg)    {       _mediator->send(msg,this);    }    void notify(std::string msg)    {       std::cout << "第一个人获得了消息:" << msg.c_str() << std::endl;    }}; class man_snd :public man{public:    man_snd(mediator* tmp) :man(tmp){}    void send(std::string msg)    {       _mediator->send(msg, this);    }    void notify(std::string msg)    {       std::cout << "第二个获得了消息:" << msg.c_str() << std::endl;    }}; class med :public mediator{public:    man_rst* _man_rst;    man_snd* _man_snd;public:    void send(std::string msg, man* tmp)    {       if (tmp == _man_rst)       {           _man_rst->notify(msg);       }       else       {           _man_snd->notify(msg);       }    }};

19、解释器模式(Interpreter)

当有一个语言需要解释执行, 并且你可将该语言中的句子表示为一个抽象语法树时,可使用解释器模式。而当存在以下情况时该模式效果最好:

该文法简单对于复杂的文法, 文法的类层次变得庞大而无法管理。此时语法分析程序生成器这样的工具是更好的选择。它们无需构建抽象语法树即可解释表达式, 这样可以节省空间而且还可能节省时间。

效率不是一个关键问题最高效的解释器通常不是通过直接解释语法分析树实现的, 而是首先将它们转换成另一种形式。例如,正则表达式通常被转换成状态机。但即使在这种情况下, 转换器仍可用解释器模式实现, 该模式仍是有用的。


class context{public:    std::string _txt_rst;    std::string _txt_snd;}; class interpreter{public:    virtual void run(context*) = 0;}; class senior_inter :public interpreter{public:    virtual void run(context* tmp)    {       std::cout << tmp->_txt_rst.c_str() << "高级解释器\n";    }}; class inferior_inter :public interpreter{public:    virtual void run(context* tmp)    {       std::cout << tmp->_txt_rst.c_str() << "次级解释器\n";    }};

20、策略模式(Strategy) 

定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。

(这个例子更像是在解释多态)


class Strategy{public:    virtual void run() = 0;}; class play :public Strategy{public:    void run()    {       std::cout << "我在玩游戏\n";    }}; class eat :public Strategy{public:    void run()    {       std::cout << "我在吃饭\n";    }}; class sleep :public Strategy{public:    void run()    {       std::cout << "我在睡觉\n";    }}; class person{private:    Strategy* _strate;public:    person(Strategy* s) :_strate(s){}    void run()    {       _strate->run();    }};

21、职责链模式(Chain of Respinsibility) 

使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

       例如公司里的事物处理可以层层递交,直到可以被解决为止(链表),事务不断向上递交直至完全执行为止


class Request{public:    std::string _str;    int _request_no;}; class manager{protected:    std::string _name;    manager* _man;public:    manager(std::string tmp)    {       _name = tmp;    }     void set_next(manager* tmp)    {       _man = tmp;    }     virtual void do_thing(Request* tmp) = 0;}; class director :public manager{public:    director(std::string str) :manager(str){}    virtual void do_thing(Request* tmp)    {       if (tmp->_request_no > 0 && tmp->_request_no < 10)       {           std::cout << _name << "完成了" << tmp->_request_no << "件工作\n";       }       else       {           std::cout << _name << "完成了" <<"10件工作\n";           tmp->_request_no -= 10;           _man->do_thing(tmp);       }     }}; class predient :public manager{public:    predient(std::string str) :manager(str){}    virtual void do_thing(Request* tmp)    {       if (tmp->_request_no > 0 && tmp->_request_no < 20)       {           std::cout << _name << "完成了" << tmp->_request_no << "件工作\n";       }       else       {           std::cout << _name << "完成了" << "20件工作\n";           tmp->_request_no -= 20;           _man->do_thing(tmp);       }     }}; class chairman :public manager{public:    chairman(std::string str) :manager(str){}    virtual void do_thing(Request* tmp)    {       if (tmp->_request_no > 0)       {           std::cout << _name << "完成了" << tmp->_request_no << "件工作\n";       }     }};

22、观察者模式(Observer)

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。      


class emp{private:    std::string _name;    int _state;public:    emp(std::string tmp,int num = 0) :_name(tmp),_state(num){}    void update()    {       if (_state > 0)       {           std::cout << "开始工作\n";       }       else       {           std::cout << "休息\n";       }    }    void set()    {       _state = 1;    }}; class observer{private:    std::vector<emp*> ptr;public:    void insert(emp* p)    {       ptr.push_back(p);    }     void act()    {       std::vector<emp*>::iterator it = ptr.begin();       for (;it < ptr.end(); it++)       {           (*it)->set();           (*it)->update();       }    }};

23、多派遣模式(Multiple Dispatching)

对于无法知道准确类型的情况适用。

这个模式只在《C++编程思想2》中看到过,其他地方无法搜索到资料

ostream& operator<< (ostream& os, outcome o){    switch (o)    {    case win:return os << "赢了\n";    case lose:return os << "输了\n";    case draw:return os << "平手\n";    }     return os;} class paper;class rock;class scissors; class index{public:    virtual outcome cmp(index* p) = 0;    virtual outcome play(const paper*)const = 0;    virtual outcome play(const rock*)const = 0;    virtual outcome play(const scissors*)const = 0;}; class paper :public index{public:    virtual outcome cmp(index* p)    {       return p->play(this);    }     virtual outcome play(const paper*)const    {       return draw;    }    virtual outcome play(const rock*)const    {       return win;    }    virtual outcome play(const scissors*)const    {       return lose;    }}; class rock :public index{public:    virtual outcome cmp(index* p)    {       return p->play(this);    }    virtual outcome play(const paper*)const    {       return lose;    }    virtual outcome play(const rock*)const    {       return draw;    }    virtual outcome play(const scissors*)const    {       return win;    }}; class scissors :public index{public:    virtual outcome cmp(index* p)    {       return p->play(this);    }    virtual outcome play(const paper*)const    {       return win;    }    virtual outcome play(const rock*)const    {       return lose;    }    virtual outcome play(const scissors*)const    {       return draw;    }}; struct compete{    outcome operator()(index* a, index* b)    {       return a->cmp(b);    }};

24、访问者模式(Vistor) 

定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。TemplateMethod 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。


class male;class female; //行为class action{public:    virtual void get_male_cl(male* tmp) = 0;    virtual void get_female_cl(female* tmp) = 0;}; //successclass success :public action{public:    virtual void get_male_cl(male* tmp)    {       std::cout << "man success\n";    }    virtual void get_female_cl(female* tmp)    {       std::cout << "female success\n";    }}; //failclass fail :public action{public:    virtual void get_male_cl(male* tmp)    {       std::cout << "man fail\n";    }    virtual void get_female_cl(female* tmp)    {       std::cout << "female fail\n";    }}; class person{public:    virtual void accept(action* tmp) = 0;}; class male :public person{public:    virtual void accept(action* tmp)    {       tmp->get_male_cl(this);    }}; class female :public person{public:    virtual void accept(action* tmp)    {       tmp->get_female_cl(this);    }}; class stuct{private:    std::vector<person*> _person;public:    void add(person* tmp)    {       _person.push_back(tmp);    }    void show(action* tmp)    {       std::vector<person*>::iterator it = _person.begin();       for (; it != _person.end(); it++)       {           (*it)->accept(tmp);       }    }};

25、备忘录模式(Memnto)

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样就可以将以后的对象状态恢复到先前保存的状态。

适用于功能比较复杂的,但需要记录或维护属性历史的类;或者需要保存的属性只是众多属性中的一小部分时Originator可以根据保存的Memo还原到前一状态。


//备忘录类class mem{public:    std::string _state;    mem(std::string tmp)    {       _state = tmp;    }}; class human{public:    std::string _state;    mem* create_mem()    {       return new mem(_state);    }    void set_mem(mem* tmp)    {       _state = tmp->_state;    }     void show()    {       std::cout << "状态:" << _state.c_str() << std::endl;    }}; class manager{public:    mem* _mem;};   int main(){    human* p = new human;    p->_state = "sb";    p->show();     //保存原始状态    manager* m = new manager;    m->_mem = p->create_mem();     //修改状态    p->_state = "on";    p->show();     //恢复    p->set_mem(m->_mem);    p->show();     system("pause");    return 0;}

三、原则 

单一职责原则

就一个类而言,应该仅有一个引起它变化的原因。

  如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其它职责能力。这种耦合会导制脆弱的设计,当变化发生时,设计会遭受到意想不到的破坏。

  如果你能够想到多于一个的动机去改变一个类,那么这个类就具有多于一个的职责。

开放――封闭原则

  软件实体可以扩展,但是不可修改。即对于扩展是开放的,对于修改是封闭的。面对需求,对程序的改动是通过增加代码来完成的,而不是改动现有的代码。

  当变化发生时,我们就创建抽象来隔离以后发生同类的变化。

  开放――封闭原则是面向对象的核心所在。开发人员应该对程序中呈现出频繁变化的那部分做出抽象,拒绝对任何部分都刻意抽象及不成熟的抽象。

里氏代换原则

  一个软件实体如果使用的是一个父类的话,那么一定适用其子类。而且它察觉不出父类对象和子类对象的区别。也就是说:在软件里面,把父类替换成子类,程序的行为没有变化。

  子类型必须能够替换掉它们的父类型。

依赖倒转原则

  抽象不应该依赖细节,细节应该依赖抽象。即针对接口编程,不要对实现编程。

  高层模块不能依赖低层模块,两者都应依赖抽象。

依赖倒转原则是面向对象的标志,用哪种语言编写程序不重要,如果编写时考虑的是如何针对抽象编程而不是针对细节编程,即程序的所有依赖关系都终止于抽象类或接口。那就是面向对象设计,反之那就是过程化设计。

迪米特法则

如果两个类不直接通信,那么这两个类就不应当发生直接的相互作用。如果一个类需要调用另一个类的某个方法的话,可以通过第三个类转发这个调用。

在类的结构设计上,每一个类都应该尽量降低成员的访问权限。

该法则在后面的适配器模式、解释模式等中有强烈的体现。


这篇文章中的内容来自于《C++编程思想2》和一些文档,代码全部为手写的,有什么错误,希望可以指出来!

0 0