设计模式(8)

来源:互联网 发布:冯巩演技 知乎 编辑:程序博客网 时间:2024/06/07 03:44

1:原型模式

定义:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。

类型:创建类模式

代码:

#include <iostream>#include <string>using namespace std;// 人的抽象类class Person{public:// 复杂的对象,需要复制的功能,应该提供一个自我复制的方法virtual Person* clone() = 0;virtual void show() = 0;};class Student :public Person{public:Student(){}Student(string name, int id){this->name  = name;this->id = id;}virtual void show(){cout << "name = " << name << ", id = " << id << endl;}virtual Person* clone(){#if 0// 1、调用赋值运算符Student *s1 = new Student();// 一个一个属性复制c/*s1->name = this->name;s1->id   = this->id;*/*s1 = *this;   // 调用默认的赋值运算符重载#endif// 调用拷贝构造Student *s1 = new Student(*this);return s1;}private:string name;int    id;};int main(){Person *p1 = new Student("wang", 10);p1->show();// 复制一个学生Person *p2 = p1->clone();p2->show();delete p1;delete p2;return 0;}
含义:

抽象层按需求提供功能和拷贝函数,利用抽象指针对对象进行拷贝和创建。

优点:使复制对象变得简单,使用原型模式创建对象比直接new一个对象在性能上要好的多,因为Object类的clone方法是一个本地方法,它直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显。并且在复制对象时不会调用构造函数。


2  代理模式

含义    Proxy模式又叫做代理模式,是构造型的设计模式之一,它可以为其他对象提供一种代理(Proxy)以控制对这个对象的访问。    
所谓代理,是指具有与代理元(被代理的对象)具有相同的接口的类,客户端必须通过代理与被代理的目标类交互,而代理一般在交互的过程中(交互前后),进行某些特别的处理。

类型  结构型模式

代码   

#include <iostream>using namespace std;// 代理与被代理的类必须都有共同的方法,把他们的方法提炼出来写成基类// 卖书的抽象基类class Subject{public:virtual void sellBook() = 0;};// 实体店卖书class RealBookStore:public Subject{public:virtual void sellBook(){cout << "实体店卖书...." << endl;}};// 代理类,淘宝:帮实体书店卖书class Taobao:public Subject{public:Taobao(){rbs = new RealBookStore;}virtual void sellBook(){cout << "淘宝卖书...." << endl;// 变着花样卖书discount();rbs->sellBook();     // 实际卖的书}void discount(){cout << "打五折" << endl;}private:RealBookStore *rbs;     // 要代理的对象};int main(){Subject *s = new Taobao;s->sellBook();return 0;}

含义 将功能封装成一个抽象类,基于该类衍射出代理子类


3  装饰模式

定义:   又叫做包装模式。通过一种对客户端透明的方式来扩展对象的功能,是继承关系的一个替换方案。
              装饰模式就是把要添加的附加功能分别放在单独的类中,并让这个类包含它要装饰的对象,当需要执行时,客户端就可以有选择地、按顺序地使用装饰功能包装对象。

类型 :  结构者模型

代码:   

#include <iostream>using namespace std;// 公共的基类class Car{public:virtual void show() = 0;};// 普通的车:能跑class RunCar:public Car{public:virtual void show(){cout << "普通车,可以跑" << endl;}};// 装饰工厂,可以让车能飞 上天class FlyCarDecorator:public Car{public:FlyCarDecorator(Car *car){this->car = car;}virtual void show(){car->show();    // 原有车的功能// -----------------添加新功能fly();          // 新添加的功能}void fly(){cout << "飞车工厂出品,能上天" << endl;}private:Car *car;};// 装饰工厂,可以让车能下海class SwimCarDecorator:public Car{public:SwimCarDecorator(Car *car){this->car = car;}virtual void show(){car->show();    // 原有车的功能// -----------------添加新功能swim();          // 新添加的功能}void swim(){cout << "海洋工厂出品, 车能下海" << endl;}private:Car *car;};int main(){Car * car = new RunCar;    // 普通的车car->show();cout << "------------------------" << endl;Car *flycar = new FlyCarDecorator(car);flycar->show();cout << "------------------------" << endl;Car *swimcar = new SwimCarDecorator(car);swimcar->show();cout << "------------------------" << endl;Car *swimFlyCar = new SwimCarDecorator(flycar);swimFlyCar->show();delete swimFlyCar;delete swimcar;delete flycar;delete car;return 0;}include <iostream>using namespace std;// 公共的基类class Car{public:virtual void show() = 0;};// 普通的车:能跑class RunCar:public Car{public:virtual void show(){cout << "普通车,可以跑" << endl;}};// 装饰工厂,可以让车能飞 上天class FlyCarDecorator:public Car{public:FlyCarDecorator(Car *car){this->car = car;}virtual void show(){car->show();    // 原有车的功能// -----------------添加新功能fly();          // 新添加的功能}void fly(){cout << "飞车工厂出品,能上天" << endl;}private:Car *car;};// 装饰工厂,可以让车能下海class SwimCarDecorator:public Car{public:SwimCarDecorator(Car *car){this->car = car;}virtual void show(){car->show();    // 原有车的功能// -----------------添加新功能swim();          // 新添加的功能}void swim(){cout << "海洋工厂出品, 车能下海" << endl;}private:Car *car;};int main(){Car * car = new RunCar;    // 普通的车car->show();cout << "------------------------" << endl;Car *flycar = new FlyCarDecorator(car);flycar->show();cout << "------------------------" << endl;Car *swimcar = new SwimCarDecorator(car);swimcar->show();cout << "------------------------" << endl;Car *swimFlyCar = new SwimCarDecorator(flycar);swimFlyCar->show();delete swimFlyCar;delete swimcar;delete flycar;delete car;return 0;}

含义:对于对象要进行扩展的功能封装成抽象类,基于抽象类有多个装饰子类,当扩展功能时建立一个新的父类指针来继承旧的指针;


4      适配器模式

定义:Adapter模式也叫适配器模式,是构造型模式之一,通过Adapter模式可以改变已有类(或外部类)的接口形式。

类型:结构者类型

代码 : 

#include <iostream>using namespace std;// 想要用的是 5vclass Current5V{public:virtual void use5V() = 0;};// 实际用电是 220Vclass Current220v{public:void use220v(){cout << "我是220v电压" << endl;}};// 适配器,是一种特殊的5v电压,是通过220v转换过来的class Adapte :public Current5V{public:Adapte(Current220v *c220v){this->current220v = c220v;}void use5V(){current220v->use220v();    // 本身使用的是220v电压cout << "经过转换, 开始使用5v电压" << endl; }private:Current220v *current220v;};int main(){Current220v *c220v = new Current220v;   // 实际220v电压Current5V *c5v = new Adapte(c220v);     // 适配器接上电压,开始转换成5v使用c5v->use5V();   // 开始用return 0;}

含义:当对象依赖与外部接口但接口中某些功能不是期望功能时,可以通过适配器重写该功能后使用;


5: 外观模式

含义:  Facade模式也叫外观模式,是由GoF提出的23种设计模式中的一种。Facade模式为一组具有类似功能的类群,比如类库,子系统等等,提供一个一致的简单的界面。这个一致的简单的界面被称作facade。

类型:  结构型模式

代码:

#include<iostream>using namespace std;class SystemA{public:void dothing(){cout << "系统A 工作" << endl;}};class SystemB{public:void dothing(){cout << "系统B 工作" << endl;}};class SystemC{public:void dothing(){cout << "系统C 工作" << endl;}};class Facade{public:Facade(){sa = new SystemA;sb = new SystemB;sc = new SystemC;}void dothing(){sa->dothing();sb->dothing();sc->dothing();}private:SystemA *sa;SystemB *sb;SystemC *sc;};int main(){// 客户端自己操作/*SystemA *sa = new SystemA;SystemB *sb = new SystemB;SystemC *sc = new SystemC;sa->dothing();sb->dothing();sc->dothing();*/Facade *facade = new Facade;facade->dothing();return 0;}

含义:为子系统中的一组接口提供一个一致的界面, Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。引入外观角色之后,用户只需要直接与外观角色交互,用户与子系统之间的复杂关系由外观角色来实现,从而降低了系统的耦合度

在遇到以下情况使用facade模式:
    1) 当你要为一个复杂子系统提供一个简单接口时。子系统往往因为不断演化而变得越来越复杂。大多数模式使用时都会产生更多更小的类。
    这使得子系统更具可重用性,也更容易对子系统进行定制,但这也给那些不需要定制子系统的用户带来一些使用上的困难。facade可以提供一个简单的缺省视图,
    这一视图对大多数用户来说已经足够,而那些需要更多的可定制性的用户可以越过facade层。
    2) 客户程序与抽象类的实现部分之间存在着很大的依赖性。引入 facade将这个子系统与客户以及其他的子系统分离,可以提高子系统的独立性 和可移植性。
    3) 当你需要构建一个层次结构的子系统时,使用 facade模式定义子系统中每层的入口点。如果子系统之间是相互依赖的,你可以让它们仅通过facade进行通讯,从而简化了它们之间的依赖关系。


6 桥接模式

定义:bridge 模式又叫做桥接模式,是构造型的设计模式之一。Bridge模式基于类的最小设计原则,通过使用封装,聚合以及继承等行为来让不同的类承担不同的责任。它的主要特点是把抽象(abstraction)与行为实现(implementation)分离开来,从而可以保持各部分的独立性以及应对它们的功能扩展

类型 构造型模式

代码  

#include <iostream>using namespace std;// 颜色的抽象类class Color{public:virtual void fillColor() = 0;};class Red:public Color{public:virtual void fillColor(){cout << "填充 红色" << endl;}};class Yellow:public Color{public:virtual void fillColor(){cout << "填充 黄色" << endl;}};class Black:public Color{public:virtual void fillColor(){cout << "填充 黑色" << endl;}};// 图形的抽象类class Shape{public:virtual void setColor(Color *color) = 0; // 设置颜色virtual void fillColor() = 0;            // 填充protected:Color *color;};class Circle:public Shape {public:virtual void setColor(Color *color){this->color = color;}virtual void fillColor(){cout << "我是 圆" << endl;color->fillColor();       // 填充颜色}};class Rectangle:public Shape {public:virtual void setColor(Color *color){this->color = color;}virtual void fillColor(){cout << "我是 矩形" << endl;color->fillColor();       // 填充颜色}};void fillColor(Shape *s, Color *c){s->setColor(c);s->fillColor();}int main(){// 颜色Color *c1 = new Red;Color *c2 = new Yellow;Color *c3 = new Black;// 图形Shape *s1 = new Circle;Shape *s2 = new Rectangle;// 图形与颜色任意组合fillColor(s1, c2);    // 圆填充黄色fillColor(s1, c3);    // 圆填充黑色fillColor(s2, c1);    // 矩形填充红色fillColor(s2, c2);    // 矩形填充黄色return 0;}

含义 : 降低实现功能对接口的依赖性,将同一类的接口化为抽象接口。


7 组合模式

定义: Composite模式也叫组合模式,是构造型的设计模式之一。通过递归手段来构造树形的对象结构,并可以通过一个对象来访问整个对象树。

类型 : 构造型模式

代码

#include <iostream>#include <string>#include <list>using namespace std;// 文件和文件夹统一操作:设置一个统一的操作方式class IFile{public:virtual void showName() = 0;virtual void add(IFile *) = 0;        // 添加文件virtual void remove(IFile *) = 0;     // 删除文件virtual list<IFile*>* gechild() = 0;  // 获取文件列表};// 普通文件class File : public IFile{public:File(string name){this->name = name;}virtual void showName(){cout << name << endl;}virtual void add(IFile *){return;}virtual void remove(IFile *){return ;}virtual list<IFile*>* gechild() {return NULL;}private:string name;};// 目录class Dir: public IFile{public:Dir(string name){this->name = name;m_list = new list<IFile*>;}~Dir(){if (m_list != NULL){// 先删除子文件while (!m_list->empty()){list<IFile*>::iterator it = m_list->begin();delete *it;m_list->erase(it);}delete m_list;m_list = NULL;}}virtual void showName(){cout << name << endl;}virtual void add(IFile *file){m_list->push_back(file);}virtual void remove(IFile *file){m_list->remove(file);delete file;}virtual list<IFile*>* gechild() {return m_list;}private:string name;list<IFile *>* m_list;};void init(IFile *root){IFile *dir1 = new Dir("电影");IFile *dir2 = new Dir("游戏");IFile *dir3 = new Dir("战狼");IFile *file1 = new File("大话西游.mp4");IFile *file2 = new File("羞羞的铁拳.mp4");IFile *file3 = new File("战狼1.mp4");IFile *file4 = new File("战狼2.mp4");IFile *file5 = new File("LOL.exe");IFile *file6 = new File("仙剑奇侠传.exe");IFile *file7 = new File("大话设计模式.pdf");IFile *file8 = new File("面试宝典.pdf");root->add(dir1);root->add(dir2);root->add(file7);root->add(file8);dir1->add(file1);dir1->add(file2);dir1->add(dir3);dir3->add(file3);dir3->add(file4);dir2->add(file5);dir2->add(file6);}// 显示结点void show(IFile *node, int gap){for (int i = 0; i < gap; i++){cout << "----";}// 1、打印自己if (node != NULL){node->showName();}elsereturn;// 2、打印子文件list<IFile*>* plist = node->gechild();if (plist != NULL)  // 代表是目录{for (list<IFile*>::iterator it = plist->begin(); it != plist->end(); it++){show(*it, gap+1);}}}int main(){IFile *root = new Dir("D盘");init(root);root->showName();//list<IFile*>* plist = root->gechild();//for (list<IFile*>::iterator it = plist->begin(); it != plist->end(); it++)//{//(*it)->showName();//}show(root, 0);return 0;}

含义 把一组相似的对象当作一个单一的对象,解耦了客户程序与复杂元素内部结构,从而使客户程序可以向处理简单元素一样来处理复杂元素。


8 观察者模式

定义:Observer模式是行为模式之一,它的作用是当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态。
   Observer模式提供给关联对象一种同步通信的手段,使某个对象与依赖它的其他对象之间保持状态同步。

类型:行为类模型

代码:

#include <iostream>#include <list>#include <string>using namespace std;class Observer;// 抽象的通知者class Subject{public:virtual void notify(string info) = 0;  // 将消息发送给所有观察者virtual void add(Observer *) = 0;      // 添加观察者virtual void remover(Observer *) = 0;  // 移除观察者protected:list<Observer *> m_list;};// 抽象的观察者class Observer{public:virtual void upadate(string info) = 0;  // 根据提供的消息进行自我更新virtual void subscribe(Subject *) = 0;  // 关注、注册、找个对象通知自己消息virtual void disScribe(Subject *) = 0;  // 取消关注};// 通知者:秘书class Secretary: public Subject{public:virtual void add(Observer *o){m_list.push_back(o);}virtual void remover(Observer *o){m_list.remove(o);}virtual void notify(string info){ // 挨个通知for (list<Observer*>::iterator it = m_list.begin(); it != m_list.end(); it++){(*it)->upadate(info);   }}};// 玩游戏class PlayGame:public Observer{public:virtual void subscribe(Subject *s){s->add(this);}virtual void disScribe(Subject *s){s->remover(this);}virtual void upadate(string info){if (info == "老板来了"){cout << "把游戏收起来,假装好好工作" << endl;}else if (info == "老板走了"){cout << "很开心, 继续玩游戏" << endl;}}};// 看电影class SeeMovie:public Observer{public:virtual void subscribe(Subject *s){s->add(this);}virtual void disScribe(Subject *s){s->remover(this);}virtual void upadate(string info){if (info == "老板来了"){cout << "把电影起来,假装好好工作" << endl;}else if (info == "老板走了"){cout << "很开心, 继续看电影" << endl;}}};// 聊天class Chat:public Observer{public:virtual void subscribe(Subject *s){s->add(this);}virtual void disScribe(Subject *s){s->remover(this);}virtual void upadate(string info){if (info == "老板来了"){cout << "把QQ关了,假装好好工作" << endl;}else if (info == "老板走了"){cout << "很开心, 继续聊天" << endl;}}};int main(){Subject *s = new Secretary;Observer *w1 = new PlayGame;Observer *w2 = new SeeMovie;Observer *w3 = new Chat;w1->subscribe(s);     // 告诉秘书,老板来了通知一声w2->subscribe(s);     // 告诉秘书,老板来了也通知一声w3->subscribe(s);     // 告诉秘书,老板来了也通知一声cout << "老板来了"<< endl;s->notify("老板来了");w3->disScribe(s);     // 要好好工作了cout << "----------------" << endl;cout << "老板走了"<< endl;s->notify("老板走了");return 0;

含义: 创建一个通知类对象,利用栈来保存观察者对象。当关注的数据发生变化时,挨个通知。