引言:本文主要介绍c++工厂模式,从低级到高级的逐步严谨。
介绍
工厂模式:这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
本文主要介绍五种工厂模式:简单工厂模式,工厂方法模式,抽象工厂模式,工厂模板模式,注册模板类+单例工厂模式,其设计思路以及兼容性、拓展性逐步递进。
简单工厂模式
简单工厂模式由工厂类,抽象产品类,具体产品类组成,简单工厂模式的工厂类中封装了创建具体产品对象的函数。以Shoes类为例进行说明
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| class Shoes { public: virtual ~Shoes(){} virtual void show() = 0; };
class NikeShoes : public Shoes { public: void show() { std::cout << "Nike!" << std::endl; } };
class AdidasShoes : public Shoes { public: void show() { std::cout << "Adidas!" << std::endl; } };
class ShoesFactory { public: enum class SHOESTYPE { NIKE, ADIDAS, }; Shoes* createShoes(SHOESTYPE type){ switch (type) { case NIKE: return new NikeShoes; break; case ADIDAS: return new AdidasShoes; break; default: return nullptr; break; } } };
int main() { ShoesFactory factory; Shoes* pNikeShoes = factory.createShoes(ShoesFactory::SHOESTYPE::NIKE); pNikeShoes->show(); Shoes* pAdidasShoes = factory.createShoes(ShoesFactory::SHOESTYPE::ADIDAS); pAdidasShoes->show(); delete pNikeShoes; delete pAdidasShoes; }
|
这种简单工厂模式的扩展性非常差,新增产品类的时候,需要去修改工厂类。
工厂方法模式
工厂方法模式是用多个工厂去生产多个产品,每个工厂只负责生产对应的产品。由抽象工厂类,具体工行类,抽象产品类,具体产品类组成。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| class Shoes { public: virtual ~Shoes(){} virtual void show() = 0; };
class NikeShoes : public Shoes { public: void show() { std::cout << "Nike!" << std::endl; } };
class AdidasShoes : public Shoes { public: void show() { std::cout << "Adidas!" << std::endl; } };
class ShoesFactory { public: virtual Shoes* createShoes() = 0; virtual ~ShoesFactory(){}; };
class NikeProducer : public ShoesFactory { public: Shoes* createShoes() { return new NiKeShoes(); } };
class AdidasProducer : public ShoesFactory { public: Shoes* createShoes() { return new AdidasShoes(); } };
int main() { ShoesFactory* nikeProducer = new NikeProducer; Shoes* pNikeShoes = nikeProducer->createShoes; pNikeShoes->show(); ShoesFactory* adidasProducer = new AdidasProducer; Shoes* pAdidasShoes = adidasProducer->createShoes; pAdidasShoes->show(); delete pNikeShoes; delete pAdidasShoes; delete nikeProducer; delete adidasProducer; }
|
工厂方法模式每新增一个产品,虽然不需要去改变已有的工厂类,但是需要新增新产品的具体工厂类,而且一个工厂只能生产一个产品。
抽象工厂模式
抽象工厂模式解决了工厂方法模式只能生产一个产品的缺点,比如想要除了Shoes要生产,还有Clothes要生产
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| class Clothes { public: virtual ~Clothes() {} virtual void show() = 0; };
class Shoes { public: virtual ~Shoes() {} virtual void show() = 0; };
class NikeClothes : public Clothes{ public: void show() { std::cout << "NikeClothes!" <<std::endl; } };
class NikeShoes : public Shoes{ public: void show() { std::cout << "NikeShoes!" << std::endl; } };
class Factory { public: virtual ~Factory() {} virtual Shoes* createShoes() = 0; virtual Clothes* createClothes() = 0; };
class NikeProducer : public Factory { Shoes* createShoes() { return new NikeShoes; } Clothes* createClothes() { return new NikeClothes; } };
|
抽象工厂模式虽然一个工厂能生产多个产品,但是还是受到新增产品的限制, 拓展性依旧很差。需要一个封装性非常强的工厂类,在新增产品时,既不需要新增工厂类,也不需要对原有的工厂类进行修改。
模板工厂模式
抽象类只需要给出相应的接口,在具体工厂类中根据传入的模板参数实现具体生产
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| class Shoes { public: virtual void show() = 0; virtual ~Shoes() {} };
class NikeShoes : public Shoes { public: void show() { std::cout << "NikeShoes!" << std::endl; } };
class AdidasShoes : public Shoes { public: void show() { std::cout << "AdidasShoes!" << std::endl; } };
class Clothes { public: virtual void show() = 0; virtual ~Clothes() {} };
class NikeClothes : public Clothes { public: void show() { std::cout << "NikeClothes!" << std::endl; } };
class AdidasClothes : public Clothes { public: void show() { std::cout << "AdidasClothes!" << std::endl; } };
template <class AbstractProduct> class AbstractFacory() { public: virtual ~AbstractFacory() {} virtual AbstractProduct* createProduct() = 0; };
template <class AbstractProduct, class ConcreteProduct> class ConcreteFactory() : public AbstractFacory<AbstractProduct> { public: AbstractProduct* createProduct() { return new ConcreteProduct; } };
int main() { ConcreteFactory<Shoes, NikeShoes> nikeFactory; Shoes* pNikShoes = nikeFactory.createProduct(); pNikeShoe->show(); delete pNikShoes; }
|
产品注册模板类+单例工厂模式
上面的模板工厂模式实现虽然在扩展性上有了极大提升,新增产品时不在需要对工厂类进行增加或者修改,但是缺少一个可以统一随时随地获取指定产品对象的类。可以把注册的对象用一个map保存起来,通过键值对的方式可以轻松获取该对象实例。一种实现方式如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| template <class ProductType> class IProductRegister { public: virtual ProductType *CreateProduct() = 0; protected: IProductRegister(){} virtual ~IProductRegister() {} private: IProductRegister(const IProductRegister&); IProductRegister& operator=(const IProductRegister&); };
template <class ProductType> class ProductFactory { public: static ProductFactory<ProductType> &Instance() { static ProductFactory<ProductType> instance; return instance; } void RegisterProduct(IProductRegister<ProductType> *register, std::string name){ m_ProductRegistry[name] = register; } ProductType* GetProduct(std::string name){ if (m_ProductRegistry.find(name)!=m_ProductRegistry.end()){ return m_ProductRegistry[name]->CreateProduct(); } std::cout << "No found " << name << std::endl; return nullptr; } private: ProductFactory() {} ~ProductFactory() {}
ProductFactory(const ProductFactory &); const ProductFactory &operator=(const ProductFactory &); std::map<std::string, IProductRegister<ProductType>*> m_ProductRegistry; };
template <class ProductType, class ProductImpl> class ProductRegistrar : public IProductRegistrar<ProductType> { explicit ProductRegistrar(std::string name) { ProductFactory<ProductType>::Instance.RegisterProduct(this, name); } ProductType *CreateProduct(){ return new ProductImpl; } };
int main() { ProductRegistrar<Shoes, NiKeShoes> nikeShoes("nike"); Shoes* pNikeShoes = ProductFactory<Shoes>::Instance.GetProduct("nike"); pNikeShoes->show(); delete pNikeShoes; }
|