一、设计模式的分类
总体来说设计模式分为三大类:
- 创建型模式,共五种:
-
单例模式
-
单例模式顾名思义,就是在系统中只允许产生这个类的一个实例。
-
实例说明:很多大臣拜见的皇帝,只有一个。体现在面向对象方面,CEmperor定义一个静态指针,和一个静态函数,私有化构造函数、析构函数、构造函数复制、重载赋值语句。
注意:线程安全,采用互斥体的方式实现
用单例的方式实现Emperor,不论在使用过程中new多少次均只会有一个实例
//Emperor.h #pragma once #include <Windows.h> #include <winnt.h> #include <iostream> using std::cout; using std::endl; using std::string; class Emperor { public: static Emperor* getInstance(); static void releaseInstance(); void emperorInfo(void); void setEmperorTag(string tag); private: Emperor(void); virtual ~Emperor(void); Emperor(const Emperor&); Emperor& operator=(const Emperor&); static Emperor *m_emperor; static HANDLE m_mutex; string m_emperor_tag; class Garbo { public: Garbo() { cout << "create garbo" << endl; } ~Garbo() { cout << "destrory garbo" << endl; getchar(); if(NULL != m_emperor) { WaitForSingleObject(m_mutex, INFINITE); if(NULL != m_emperor) { cout << "remove instance" << endl; delete m_emperor; m_emperor = NULL; } ReleaseMutex(m_mutex); } if(NULL != m_mutex) { cout << "delete mutex" << endl; CloseHandle(m_mutex); m_mutex = NULL; } } }; static Garbo m_garbo; }; //Emperor.cpp #include "stdafx.h" #include "Emperor.h" #include <iostream> using std::cout; using std::endl; using std::string; Emperor *Emperor::m_emperor = NULL; HANDLE Emperor::m_mutex = CreateMutex(NULL, FALSE, NULL); Emperor::Garbo Emperor::m_garbo; Emperor::Emperor(void) { cout << "create emperor instance" << endl; } Emperor::~Emperor(void) { cout << "destroy emperor instance and release its resources" << endl; } void Emperor::emperorInfo(void) { char msg_buf[50] = {0}; sprintf_s(msg_buf, 50, "the emperor's name is (%s)", m_emperor_tag.c_str()); string msg(msg_buf); cout << msg.c_str() << endl; } Emperor *Emperor::getInstance() { if(NULL == m_emperor) { WaitForSingleObject(m_mutex, INFINITE); if(NULL == m_emperor) m_emperor = new Emperor(); ReleaseMutex(m_mutex); } return m_emperor; } void Emperor::releaseInstance() { if(NULL != m_emperor) { WaitForSingleObject(m_mutex, INFINITE); if(NULL != m_emperor) { delete m_emperor; m_emperor = NULL; } ReleaseMutex(m_mutex); } } void Emperor::setEmperorTag(string tag) { m_emperor_tag = tag; } // SingletoPatternDemo.cpp : 定义控制台应用程序的入口点。 #include "stdafx.h" #include "Emperor.h" int _tmain(int argc, _TCHAR* argv[]) { Emperor *pEmperor1 = Emperor::getInstance(); pEmperor1->setEmperorTag("QL"); pEmperor1->emperorInfo(); Emperor *pEmperor2 = Emperor::getInstance(); pEmperor2->emperorInfo(); Emperor *pEmperor3 = Emperor::getInstance(); pEmperor3->emperorInfo(); Emperor::releaseInstance(); getchar(); return 0; }
-
-
原型模式
- 从类到对象叫作“创建”,而由本体对象至副本对象则叫作“克隆”,当需要创建多个类似的复杂对象时,我们就可以考虑用原型模式。究其本质,克隆操作时直接拷贝原型对象数据流生成新的副本对象,绝不会拖泥带水地触发一些多余的复杂操作(如类加载、实例化、初始化等),所以其效率远远高于“new”关键字所触发的实例化操作。原型模式实现的关键就是实现Clone函数,对于C++来说,其实就是拷贝构造函数,需实现深拷贝,下面给出一种实现。
//父类 class Resume { protected: char *name; public: Resume() {} virtual ~Resume() {} virtual Resume* Clone() { return NULL; } virtual void Set(char *n) {} virtual void Show() {} }; class ResumeA : public Resume { public: ResumeA(const char *str); //构造函数 ResumeA(const ResumeA &r); //拷贝构造函数 ~ResumeA(); //析构函数 ResumeA* Clone(); //克隆,关键所在 void Show(); //显示内容 }; ResumeA::ResumeA(const char *str) { if(str == NULL) { name = new char[1]; name[0] = '\0'; } else { name = new char[strlen(str)+1]; strcpy(name, str); } } ResumeA::~ResumeA() { delete [] name;} ResumeA::ResumeA(const ResumeA &r) { name = new char[strlen(r.name)+1]; strcpy(name, r.name); } ResumeA* ResumeA::Clone() { return new ResumeA(*this); } void ResumeA::Show() { cout<<"ResumeA name : "<<name<<endl; } int main() { Resume *r1 = new ResumeA("A"); Resume *r2 = new ResumeB("B"); Resume *r3 = r1->Clone(); Resume *r4 = r2->Clone(); r1->Show(); r2->Show(); //删除r1,r2 delete r1; delete r2; r1 = r2 = NULL; //深拷贝所以对r3,r4无影响 r3->Show(); r4->Show(); delete r3; delete r4; r3 = r4 = NULL; }
-
工厂方法模式
- 简单工厂模式,主要特点是需要在工厂类中做判断,从而创造相应的产品。当增加新的产品时,就需要修改工厂类。
enum CTYPE {COREA, COREB}; class SingleCore { public: virtual void Show() = 0; }; //单核A class SingleCoreA: public SingleCore { public: void Show() { cout<<"SingleCore A"<<endl; } }; //单核B class SingleCoreB: public SingleCore { public: void Show() { cout<<"SingleCore B"<<endl; } }; //唯一的工厂,可以生产两种型号的处理器核,在内部判断 class Factory { public: SingleCore* CreateSingleCore(enum CTYPE ctype) { if(ctype == COREA) //工厂内部判断 return new SingleCoreA(); //生产核A else if(ctype == COREB) return new SingleCoreB(); //生产核B else return NULL; } };
- 工厂方法模式
- 工厂方法模式每增加一种产品,就需要增加一个对象的工厂。如果这家公司发展迅速,推出了很多新的处理器核,那么就要开设相应的新工厂。在C++实现中,就是要定义一个个的工厂类。显然,相比简单工厂模式,工厂方法模式需要更多的类定义
class SingleCore { public: virtual void Show() = 0; }; //单核A class SingleCoreA: public SingleCore { public: void Show() { cout<<"SingleCore A"<<endl; } }; //单核B class SingleCoreB: public SingleCore { public: void Show() { cout<<"SingleCore B"<<endl; } }; class Factory { public: virtual SingleCore* CreateSingleCore() = 0; }; //生产A核的工厂 class FactoryA: public Factory { public: SingleCoreA* CreateSingleCore() { return new SingleCoreA; } }; //生产B核的工厂 class FactoryB: public Factory { public: SingleCoreB* CreateSingleCore() { return new SingleCoreB; } };
- 工厂方法模式每增加一种产品,就需要增加一个对象的工厂。如果这家公司发展迅速,推出了很多新的处理器核,那么就要开设相应的新工厂。在C++实现中,就是要定义一个个的工厂类。显然,相比简单工厂模式,工厂方法模式需要更多的类定义
- 抽象工厂模式
- 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。 抽象工厂模式(Abstract Factory)是对工厂的抽象化,而不只是制造方法。我们知道,为了满足不同用户对产品的多样化需求,工厂不会只局限于生产一类产品,但是系统如果按工厂方法那样为每种产品都增加一个新工厂又会造成工厂泛滥。所以,为了调和这种矛盾,抽象工厂模式提供了另一种思路,将各种产品分门别类,基于此来规划各种工厂的制造接口,最终确立产品制造的顶级规范,使其与具体产品彻底脱钩。抽象工厂是建立在制造复杂产品体系需求基础之上的一种设计模式,在某种意义上,我们可以将抽象工厂模式理解为工厂方法模式的高度集群化升级版
//单核 class SingleCore { public: virtual void Show() = 0; }; class SingleCoreA: public SingleCore { public: void Show() { cout<<"Single Core A"<<endl; } }; class SingleCoreB :public SingleCore { public: void Show() { cout<<"Single Core B"<<endl; } }; //多核 class MultiCore { public: virtual void Show() = 0; }; class MultiCoreA : public MultiCore { public: void Show() { cout<<"Multi Core A"<<endl; } }; class MultiCoreB : public MultiCore { public: void Show() { cout<<"Multi Core B"<<endl; } }; //工厂 class CoreFactory { public: virtual SingleCore* CreateSingleCore() = 0; virtual MultiCore* CreateMultiCore() = 0; }; //工厂A,专门用来生产A型号的处理器 class FactoryA :public CoreFactory { public: SingleCore* CreateSingleCore() { return new SingleCoreA(); } MultiCore* CreateMultiCore() { return new MultiCoreA(); } }; //工厂B,专门用来生产B型号的处理器 class FactoryB : public CoreFactory { public: SingleCore* CreateSingleCore() { return new SingleCoreB(); } MultiCore* CreateMultiCore() { return new MultiCoreB(); } };
-
建造者模式
- 建造者模式的定义将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示(DP)。例子——建造小人,一共需建造6个部分,头部、身体、左右手、左右脚。与工厂模式不同,建造者模式是在
导向者
的控制下一步一步构造产品的。建造小人就是在控制下一步步构造出来的。创建者模式可以能更精细的控制构建过程,从而能更精细的控制所得产品的内部结构。 - 建造者模式(Builder)所构建的对象一定是庞大而复杂的,并且一定是按照既定的制造工序将组件组装起来的,例如计算机、汽车、建筑物等。我们通常将负责构建这些大型对象的工程师称为建造者。建造者模式又称为生成器模式,主要用于对复杂对象的构建、初始化,它可以将多个简单的组件对象按顺序一步步组装起来,最终构建成一个复杂的成品对象。与工厂系列模式不同的是,建造者模式的主要目的在于把烦琐的构建过程从不同对象中抽离出来,使其脱离并独立于产品类与工厂类,最终实现用同一套标准的制造工序能够产出不同的产品。
class Builder { public: virtual void BuildHead() {} virtual void BuildBody() {} virtual void BuildLeftArm(){} virtual void BuildRightArm() {} virtual void BuildLeftLeg() {} virtual void BuildRightLeg() {} }; //构造瘦人 class ThinBuilder : public Builder { public: void BuildHead() { cout<<"build thin body"<<endl; } void BuildBody() { cout<<"build thin head"<<endl; } void BuildLeftArm() { cout<<"build thin leftarm"<<endl; } void BuildRightArm() { cout<<"build thin rightarm"<<endl; } void BuildLeftLeg() { cout<<"build thin leftleg"<<endl; } void BuildRightLeg() { cout<<"build thin rightleg"<<endl; } }; //构造胖人 class FatBuilder : public Builder { public: void BuildHead() { cout<<"build fat body"<<endl; } void BuildBody() { cout<<"build fat head"<<endl; } void BuildLeftArm() { cout<<"build fat leftarm"<<endl; } void BuildRightArm() { cout<<"build fat rightarm"<<endl; } void BuildLeftLeg() { cout<<"build fat leftleg"<<endl; } void BuildRightLeg() { cout<<"build fat rightleg"<<endl; } }; //构造的指挥官 class Director { private: Builder *m_pBuilder; public: Director(Builder *builder) { m_pBuilder = builder; } void Create(){ m_pBuilder->BuildHead(); m_pBuilder->BuildBody(); m_pBuilder->BuildLeftArm(); m_pBuilder->BuildRightArm(); m_pBuilder->BuildLeftLeg(); m_pBuilder->BuildRightLeg(); } }; int main() { FatBuilder thin; Director director(&thin); director.Create(); return 0; }
- 建造者模式的定义将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示(DP)。例子——建造小人,一共需建造6个部分,头部、身体、左右手、左右脚。与工厂模式不同,建造者模式是在
-