单例设计模式和工厂设计模式
单例设计模式和工厂设计模式
这是楼主根据别人的博客整理的面试中问得比较多的设计模式,即单例设计模式和工厂设计模式;
这个链接的原博主使用图文结合的方式来讲解设计模式,简单通俗易懂,分享给大家~
如果想学习更多设计模式,可以点击下面的原文链接:设计模式原文链接
单例设计模式
保证一个类只有一个实例,并提供一个访问它的全局访问点。
首先,需要保证一个类只有一个实例;
在类中,要构造一个实例,就必须调用类的构造函数,为了防止在外部调用类的构造函数而构造实例,需要将构造函数的访问权限标记为protected或private;
最后,需要提供要给全局访问点,就需要在类中定义一个static函数,返回在类内部唯一构造的实例。
#include <iostream> using namespace std; class Singleton { public: static Singleton *GetInstance() //获取一个实例 { if (m_Instance == NULL ) { m_Instance = new Singleton (); } return m_Instance; } static void DestoryInstance() //析构函数 { if (m_Instance != NULL ) { delete m_Instance; m_Instance = NULL ; } } // This is just a operation example int GetTest() { return m_Test; } private: Singleton(){ m_Test = 10; } //将构造函数定义成私有函数,即只能父类进行调用 static Singleton *m_Instance; //用来指向父类创建的唯一一个实例 int m_Test; //测试用 }; Singleton *Singleton ::m_Instance = NULL; //初始化类静态变量 int main(int argc , char *argv []) { Singleton *singletonObj = Singleton ::GetInstance(); cout<<singletonObj->GetTest()<<endl; Singleton ::DestoryInstance(); return 0; }
工厂模式
简单工厂模式
简单工厂模式有一种非常形象的描述,建立对象的类就如一个工厂,而需要被建立的对象就是一个个产品;
在工厂中加工产品,使用产品的人,不用在乎产品是如何生产出来的。从软件开发的角度来说,这样就有效的降低了模块之间的耦合。
ProductA、ProductB和ProductC继承自Product虚拟类,Show方法是不同产品的自描述;Factory依赖于ProductA、ProductB和ProductC,Factory根据不同的条件创建不同的Product对象。
适用场合
在程序中,需要创建的对象很多,导致对象的new操作多且杂时,需要使用简单工厂模式;
由于对象的创建过程是我们不需要去关心的,而我们注重的是对象的实际操作;
所以,我们需要分离对象的创建和操作两部分,如此,方便后期的程序扩展和维护。
#include<iostream> #include<vector> using namespace std; typedef enum ProductTypeTag{ TypeA, TypeB, TypeC }PRODUCTTYPE; // Here is the product class class Product{ public: virtual void Show()= 0; }; class ProductA :public Product{ public: void Show(){ cout<<"I'm ProductA"<<endl; } }; class ProductB :public Product{ public: void Show(){ cout<<"I'm ProductB"<<endl; } }; class ProductC :public Product{ public: void Show(){ cout<<"I'm ProductC"<<endl; } }; // Here is the Factory class class Factory{ public: Product* CreateProduct(PRODUCTTYPE type){ switch (type){ case TypeA: returnnew ProductA(); case TypeB: returnnew ProductB(); case TypeC: returnnew ProductC(); default: return NULL; } } }; int main(int argc, char *argv[]){ // First, create a factory object Factory *ProductFactory = new Factory(); Product *productObjA = ProductFactory->CreateProduct(TypeA); if (productObjA != NULL) productObjA->Show(); Product *productObjB = ProductFactory->CreateProduct(TypeB); if (productObjB != NULL) productObjB->Show(); Product *productObjC = ProductFactory->CreateProduct(TypeC); if (productObjC != NULL) productObjC->Show(); delete ProductFactory; ProductFactory = NULL; delete productObjA; productObjA = NULL; delete productObjB; productObjB = NULL; delete productObjC; productObjC = NULL; return 0; }
工厂方法模式
工厂方法模式是在简单工厂模式的基础上,对“工厂”添加了一个抽象层。将工厂共同的动作抽象出来,作为抽象类,而具体的行为由子类本身去实现,让子类去决定生产什么样的产品。
如图,FactoryA专心负责生产ProductA,FactoryB专心负责生产ProductB,FactoryA和FactoryB之间没有关系;
如果到了后期,如果需要生产ProductC时,我们则可以创建一个FactoryC工厂类,该类专心负责生产ProductC类产品。
由于FactoryA、FactoryB和FactoryC之间没有关系,当加入FactoryC加入时,对FactoryA和FactoryB的工作没有产生任何影响,那么对代码进行测试时,只需要单独对FactoryC和ProductC进行单元测试,而FactoryA和FactoryB则不用进行测试,则可省去大量无趣无味的测试工作。
适用场合
工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口;
这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。
在设计的初期,就考虑到产品在后期会进行扩展的情况下,可以使用工厂方法模式;
产品结构较复杂的情况下,可以使用工厂方法模式;
#include<iostream> using namespace std; class Product{ public: virtualvoidShow()= 0; }; class ProductA :public Product{ public: voidShow(){ cout<< "I'm ProductA"<<endl; } }; class ProductB :public Product{ public: voidShow(){ cout<< "I'm ProductB"<<endl; } }; class Factory{ public: virtual Product *CreateProduct()= 0; }; class FactoryA :public Factory{ public: Product *CreateProduct(){ return new ProductA (); } }; class FactoryB :public Factory{ public: Product *CreateProduct(){ return new ProductB (); } }; int main(int argc , char *argv []){ Factory *factoryA = new FactoryA (); Product *productA = factoryA->CreateProduct(); productA->Show(); Factory *factoryB = new FactoryB (); Product *productB = factoryB->CreateProduct(); productB->Show(); if (factoryA != NULL){ delete factoryA; factoryA = NULL; } if (productA != NULL){ delete productA; productA = NULL; } if (factoryB != NULL){ delete factoryB; factoryB = NULL; } if (productB != NULL){ delete productB; productB = NULL; } return 0; }
抽象工厂模式
如图所示,抽象工厂模式,就好比是两个工厂方法模式的叠加。
抽象工厂创建的是一系列相关的对象,其中创建的实现其实就是采用的工厂方法模式。在工厂Factory中的每一个方法,就好比是一条生产线,而生产线实际需要生产什么样的产品,这是由Factory1和Factory2去决定的,这便延迟了具体子类的实例化;
同时集中化了生产线的管理,节省了资源的浪费。
适用场合
工厂方法模式适用于产品种类结构单一的场合,为一类产品提供创建的接口;而抽象工厂方法适用于产品种类结构多的场合;
主要用于创建一组(有多个种类)相关的产品,为它们提供创建的接口;就是当具有多个抽象角色时,抽象工厂便可以派上用场。
#include<iostream> using namespace std; // Product A class ProductA{ public: virtual void Show()= 0; }; class ProductA1 :public ProductA{ public: void Show(){ cout<<"I'm ProductA1"<<endl; } }; class ProductA2 :public ProductA{ public: void Show(){ cout<<"I'm ProductA2"<<endl; } }; // Product B class ProductB{ public: virtual voidShow()= 0; }; class ProductB1 :public ProductB { public: voidShow(){ cout<<"I'm ProductB1"<<endl; } }; class ProductB2 :public ProductB{ public: voidShow(){ cout<<"I'm ProductB2"<<endl; } }; // Factory class Factory{ public: virtual ProductA *CreateProductA()= 0; virtual ProductB *CreateProductB()= 0; }; class Factory1 :public Factory{ public: ProductA *CreateProductA(){ return new ProductA1(); } ProductB *CreateProductB(){ return new ProductB1(); } }; class Factory2 :public Factory { ProductA *CreateProductA(){ return new ProductA2(); } ProductB *CreateProductB(){ return new ProductB2(); } }; int main(int argc, char *argv[]){ Factory *factoryObj1 = new Factory1(); ProductA *productObjA1 = factoryObj1->CreateProductA(); ProductB *productObjB1 = factoryObj1->CreateProductB(); productObjA1->Show(); productObjB1->Show(); Factory *factoryObj2 = new Factory2(); ProductA *productObjA2 = factoryObj2->CreateProductA(); ProductB *productObjB2 = factoryObj2->CreateProductB(); productObjA2->Show(); productObjB2->Show(); if(factoryObj1 != NULL){ delete factoryObj1; factoryObj1 = NULL; } if(productObjA1 != NULL){ delete productObjA1; productObjA1= NULL; } if(productObjB1 != NULL){ delete productObjB1; productObjB1 = NULL; } if(factoryObj2 != NULL){ delete factoryObj2; factoryObj2 = NULL; } if(productObjA2 != NULL){ delete productObjA2; productObjA2 = NULL; } if(productObjB2 != NULL){ delete productObjB2; productObjB2 = NULL; } }