设计模式概览续(结构型模式)

来源:互联网 发布:端口号地址 编辑:程序博客网 时间:2024/06/01 09:39
       上一篇介绍了创建型模式http://blog.csdn.net/songshimvp1/article/details/48786615——单例模式、简单工厂模式,多态工厂模式、抽象工厂模式、建造者模式、原型模式(prototype),接下来介绍结构型模式——代理模式、装饰模式、适配器模式(adapter)、组合模式、桥接模式(bridge)、外观模式(facade)、享元模式(flyweight)。

设计模式详解之——结构型模式

1、代理模式(Proxy)★

Proxy模式,代理模式,是构造型的设计模式之一,它可以为其他对象提供一种代理(Proxy)以控制对这个对象的访问。所谓代理,是指具有与代理元(被代理的对象)具有 相同的接口 的类,客户端必须通过 代理与被代理的目标类 交互,而代理一般在交互的过程中(交互前后)进行某些特别的处理。适合于:为其他对象提供一种代理以控制对这个对象的访问。实现:a中包含b类;a、b类实现协议类protocol 。
真实玩家(李),代理玩家(赵);代理玩家(赵),代替(李),进行升级打怪。
/*出版社,为被代理对象,要卖书;淘宝、当当网(网上书店),为代理对象;客户端通过当当网进行买书;*/#include<iostream>using namespace std;class Subject  //抽象层,作为真实主题(RealSubject)和代理主题(Proxy)的共同接口{public:virtual void sailbook() = 0;};//真实主题角色:定义了代理角色所代表的真实对象class RealSubjectBook :public Subject   {public:virtual void sailbook(){cout << "实体店卖书..." << endl;}};//a中包含b类;a、b类实现协议类protocol//代理主题角色:代理角色通常在将 客户端调用 传递给 真实对象 之前或者之后 执行某些操作,而不是单纯返回 真实对象class dangdangProxy : public Subject   {public:void SetRealSubject(){RealSubjectBook *rs = new RealSubjectBook;m_subject = rs;}virtual void sailbook(){SetRealSubject();dazhe();    //执行打折操作m_subject->sailbook();}void dazhe(){cout << "当当 双十一打折半价..." << endl;}private:RealSubjectBook *m_subject;};void main(){Subject *s = new dangdangProxy;s->sailbook();delete s;}

2、装饰模式(decorator)★

装饰( Decorator )模式又叫做包装模式。通过一种对客户端透明的方式来扩展对象的功能,是继承关系的一个替换方案。装饰模式就是把要添加的附加功能分别放在单独的类中,并让这个类包含它要装饰的对象,当需要执行时,客户端就可以有选择地、按顺序地使用装饰功能包装对象。适用于:装饰模式(Decorator Pattern)动态的给一个对象添加一些额外的职责。就增加功能来说,此模式比生成子类更为灵活。
#include<iostream>using namespace std;class Car{public:virtual void show() = 0;};class RunCar :public Car{public:virtual void show(){cout << "可以跑!" << endl;}};class SwimCarDirector :public Car{public:SwimCarDirector(Car *car){m_car = car;}void SwimCar(){cout << "可以游!" << endl;}virtual void show(){m_car->show();SwimCar();}private:Car* m_car;};class FlyCarDirector :public Car{public:FlyCarDirector(Car *car){mm_car = car;}void FlyCar(){cout << "可以飞!" << endl;}virtual void show(){mm_car->show();FlyCar();}private:Car* mm_car;};void main(){Car *mycar = NULL;mycar = new RunCar;cout << "初级:---" << endl;mycar->show();cout << endl;cout << "升级游:---" << endl;SwimCarDirector *myswimcar = new SwimCarDirector(mycar);   //自由组合装饰类(增加的功能的单独封装)myswimcar->show();cout << endl;cout << "升级飞:---" << endl;FlyCarDirector *myflycar = new FlyCarDirector(myswimcar);   //自由组合装饰类(增加的功能的单独封装)myflycar->show();delete mycar;delete myflycar;delete myswimcar;}

3、适配器模式(adapter)★

通过Adapter模式可以改变已有类(或外部类)的接口形式。适用于:是将一个类的接口转换成客户希望的另外一个接口。使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
class  Current18v   //希望使用电压18V{public:virtual void useCurrent18v() = 0;};class  Current220v  //现有电压220V{public:void useCurrent220v(){cout << "我是220v,欢迎使用..." << endl;}};class Adapter : public Current18v  //适配器:转换接口{public:Adapter(Current220v *current){m_current = current;}virtual void useCurrent18v(){cout << "适配器,适配 220v:——";m_current->useCurrent220v();}private:Current220v *m_current;   //关联};void main(){Current220v*current220v = NULL;Adapter*adapter = NULL;current220v = new Current220v;adapter = new Adapter(current220v);adapter->useCurrent18v();//客户端通过适配器使用18V,但是在适配器内部使用220Vdelete current220v;delete adapter;}

4、组合模式(composite)

Composite模式也叫组合模式,是构造型的设计模式之一。通过递归手段来构造树形的对象结构,并可以通过一个对象来访问整个对象树。适用于:单个对象和组合对象的使用具有一致性。将对象组合成树形结构以表示“部分--整体”    
class IFile{public:virtual void display() = 0;virtual int add(IFile *ifile) = 0;virtual int remove(IFile *ifile) = 0;virtual list<IFile *> *getChild() = 0;};//文件 结点 class File : public IFile{public:File(string name){m_name = name;}virtual void display(){cout << m_name << endl;}virtual int add(IFile *ifile){return -1;}virtual int remove(IFile *ifile){return -1;}virtual list<IFile *> *getChild(){return NULL;}private:string m_name;};//目录 结点 class Dir : public IFile{public:Dir(string name){m_name = name;m_list = new list<IFile *>;m_list->clear();}virtual void display(){cout << m_name << endl;}virtual int add(IFile *ifile){m_list->push_back(ifile);return 0;}virtual int remove(IFile *ifile){m_list->remove(ifile);return 0;}virtual list<IFile *> *getChild(){return m_list;}private:string m_name;list<IFile *>  *m_list;};//递归的显示树void showTree(IFile *root, int level){int i = 0;if (root == NULL){return;}for (i = 0; i<level; i++){printf("\t");}//1 显示根 结点root->display();//2  若根结点 有孩子 //判读孩子是文件,显示名字 )//判断孩子是目录,showTree(子目录)list<IFile *>  *mylist = root->getChild();if (mylist != NULL)   //说明是一个目录{for (list<IFile *>::iterator it = mylist->begin(); it != mylist->end(); it++){if ((*it)->getChild() == NULL){for (i = 0; i <= level; i++)  //注意 <= {printf("\t");}(*it)->display();   //显示叶子结点}else{showTree(*it, level + 1);   //显示子目录}}}}void main(){Dir *root = new Dir("C");//root->display();Dir *dir1 = new Dir("111dir");File *aaafile = new File("aaa.txt");//获取root结点下的 孩子集合list<IFile *>  *mylist = root->getChild();root->add(dir1);root->add(aaafile);//  (111dir)   (aaa.txt)//▲for (list<IFile *>::iterator it = mylist->begin(); it != mylist->end(); it++){(*it)->display();}Dir *dir222 = new Dir("222dir");File *bbbfile = new File("bbb.txt");dir1->add(dir222);dir1->add(bbbfile);cout << "通过 showTree 方式 显示 root 结点下的 所有子结点" << endl;showTree(root, 0);}

5、桥接模式(bridge)★

       Bridge模式基于类的最小设计原则,通过使用封装、聚合以及继承等行为来让 不同的类 承担 不同的责任。它的主要特点是 把 抽象(abstraction) 与 行为实现(implementation)  分离开来,从而可以保持 各部分的独立性 以及 对应它们的功能扩展。适用于:桥接模式(Bridge Pattern)是将抽象部分与实现部分分离(解耦合),使它们都可以独立的变化。车 安装 发动机 ;不同型号的车,安装不同型号的发动机,将“车 安装 发动机”这个抽象 和 实现进行分离,两个名字 就设计两个类!
       如果抽象出不同的车型、不同型号的发动机,然后不同类型的车去安装不同类型的发动机,但是事实上车和发动机之间的会有交叉(多对多),如果用继承的方式,会引起子类的泛滥。所以需要把“安装发动机”这个事,做很好的分解;把 抽象 和 行为实现 分开。
       再比如:图形的填充,图形有多个(矩形、正方形,圆、椭圆等),颜色也有很多种(红、橙、黄、绿等),不同的图形可以填充不同的颜色,如果用继承去实现“填充”这一动作,显然非常不合理。
  
//所以需要把“安装发动机”这个事,做很好的分解;把 抽象 和 行为实现 分开//发动机class Engine{public:virtual void InstallEngine() = 0;  //动作的真正实现在发动机完成,而动作的定义在“车”类里面};class Engine4400cc : public Engine{public:virtual void InstallEngine(){cout << "我是 4400cc 发动机 安装完毕 " << endl;}};class Engine4500cc : public Engine{public:virtual void InstallEngine(){cout << "我是 4500cc 发动机,安装完毕 " << endl;}};//车class Car{public:Car(Engine *engine){this->m_engine = engine;}virtual void installEngine() = 0;   //安装发动机的动作的定义protected:Engine *m_engine;                   //抽象类之间进行桥接};class BMW5 : public Car{public:BMW5(Engine *engine) : Car(engine){;}virtual void installEngine(){m_engine->InstallEngine();      //安装发动机的动作的实现——Engine}};class BMW6 : public Car{public:BMW6(Engine *engine) : Car(engine){;}//注意 车的安装 和 发动机的安装 的不同之处virtual void installEngine(){cout << "我是 BMW6 " << endl;m_engine->InstallEngine();     //动作的实现}};//抽象一个car基类和engine基类,客户端面向抽象基类编程void main(){Engine*engine = NULL;BMW6*bmw6 = NULL;engine = new Engine4400cc;bmw6 = new BMW6(engine);bmw6->installEngine();delete bmw6;delete engine;}

6、外观模式(facade)

Facade模式为一组具有类似功能的类群,比如类库,子系统等等,提供一个一致的简单的界面。这个一致的简单的界面被称作facade。适用于:为子系统中统一一套接口,让子系统更加容易使用。
class SubSystemA{public:void doThing(){cout << "SubSystemA run" << endl;}};class SubSystemB{public:void doThing(){cout << "SubSystemB run" << endl;}};class SubSystemC{public:void doThing(){cout << "SubSystemC run" << endl;}};class Facade{public:Facade(){sysA = new SubSystemA;sysB = new SubSystemB;sysC = new SubSystemC;}~Facade(){delete sysA;delete sysB;delete sysC;}public:void doThing(){sysA->doThing();sysB->doThing();sysC->doThing();}private:SubSystemA *sysA;SubSystemB *sysB;SubSystemC *sysC;};void main001()    //旧的方式{SubSystemA *sysA = new SubSystemA;SubSystemB *sysB = new SubSystemB;SubSystemC *sysC = new SubSystemC;sysA->doThing();sysB->doThing();sysC->doThing();delete sysA;delete sysB;delete sysC;}void main08()   //新的模式——使用外观模式{Facade *f = new Facade;f->doThing();delete f;}

7、享元模式(flyweight)

Flyweight模式也叫享元模式,是构造型模式之一,它通过与其他类似对象共享数据来减小内存占用。使用场景:以共享的方式,高效的支持大量的细粒度的对象。
class Person{public:Person(string name, int age){this->m_name = name;this->age = age;}virtual void printT() = 0;protected:stringm_name;intage;};class Teacher : public Person{public:Teacher(string name, int age, string id) : Person(name, age){this->m_id = id;}void printT(){cout << "name:" << m_name << " age:" << age << " m_id:" << m_id << endl;}private:stringm_id;};//完成 老师结点 存储class FlyWeightTeacherFactory{public:FlyWeightTeacherFactory(){map1.clear();}~FlyWeightTeacherFactory()  //防止内存泄露,因为每个Teacher都是new出来的{while (!map1.empty()){Person *tmp = NULL;map<string, Person *>::iterator it = map1.begin();tmp = it->second;map1.erase(it);     //把第一个结点 从容器中删除delete tmp;}}Person* GetTeacher(string id){Person *tmp = NULL;map<string, Person *>::iterator it;it = map1.find(id);if (it == map1.end())  //没有找到{stringtmpname;inttmpage;cout << "\n请输入老师name:";cin >> tmpname;cout << "\n请输入老师 age:";cin >> tmpage;tmp = new Teacher(tmpname, tmpage, id);map1.insert(pair<string, Person*>(id, tmp));}else{tmp = it->second;   //Person*}return tmp;}private:map<string, Person*> map1;};void main009(){Person *p1 = NULL;Person *p2 = NULL;FlyWeightTeacherFactory *fwtf = new FlyWeightTeacherFactory;p1 = fwtf->GetTeacher("001");   //第一次获取p1->printT();p2 = fwtf->GetTeacher("001");   //第二次获取p2->printT();delete fwtf;}

       上述介绍了结构型模式——代理模式、装饰模式、适配器模式(adapter)、组合模式、桥接模式(bridge)、外观模式(facade)、享元模式(flyweight)。接下来介绍行为型模式http://blog.csdn.net/songshimvp1/article/details/48970017——模板模式(template)、命令模式(command)、责任链模式、策略模式、中介者模式(mediator)、观察者模式(observer)、备忘录模式(mememto)、访问者模式(visitor)、状态模式(state)、解释模式(interpreter)、迭代器模式(iterator)。
0 0
原创粉丝点击