我们先看工厂模式的介绍
这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
简单来说,使用了C++多态的特性,将存在继承关系的类,通过一个工厂类创建对应的子类(派生类)对象。在项目复杂的情况下,可以便于子类对象的创建。
工厂模式的实现方式可分别简单工厂模式、工厂方法模式、抽象工厂模式,每个实现方式都存在优和劣。
假想你是一个温州鞋老板,资金不多,代理做各种鞋子,例如:耐克,阿迪, 李宁 。
ShoesFactory
是你的工厂,有3条生产线,负责生产这3种鞋子 NiKeShoes\AdidasShoes\LiNingShoes
。人手少,你得负责这3条生产线的管理,把你抽象成一个鞋子类 Shoes
。
代码如下:
#includeusing namespace std; // 鞋子抽象类 class Shoes { public: virtual ~Shoes() {} virtual void Show() = 0; }; // 耐克鞋子 class NiKeShoes : public Shoes { public: void Show() { std::cout << "我是耐克球鞋,我的广告语:Just do it" << std::endl; } }; // 阿迪达斯鞋子 class AdidasShoes : public Shoes { public: void Show() { std::cout << "我是阿迪达斯球鞋,我的广告语:Impossible is nothing" << std::endl; } }; // 李宁鞋子 class LiNingShoes : public Shoes { public: void Show() { std::cout << "我是李宁球鞋,我的广告语:Everything is possible" << std::endl; } }; enum SHOES_TYPE { NIKE, LINING, ADIDAS }; // 总鞋厂 class ShoesFactory { public: // 根据鞋子类型创建对应的鞋子对象 Shoes *CreateShoes(SHOES_TYPE type) { switch (type) { case NIKE: return new NiKeShoes(); break; case LINING: return new LiNingShoes(); break; case ADIDAS: return new AdidasShoes(); break; default: return NULL; break; } } }; int main() { // 构造工厂对象 ShoesFactory shoesFactory; // 从鞋工厂对象创建阿迪达斯鞋对象 Shoes *pNikeShoes = shoesFactory.CreateShoes(NIKE); if (pNikeShoes != NULL) { // 耐克球鞋广告喊起 pNikeShoes->Show(); // 释放资源 delete pNikeShoes; pNikeShoes = NULL; } // 从鞋工厂对象创建阿迪达斯鞋对象 Shoes *pLiNingShoes = shoesFactory.CreateShoes(LINING); if (pLiNingShoes != NULL) { // 李宁球鞋广告喊起 pLiNingShoes->Show(); // 释放资源 delete pLiNingShoes; pLiNingShoes = NULL; } // 从鞋工厂对象创建阿迪达斯鞋对象 Shoes *pAdidasShoes = shoesFactory.CreateShoes(ADIDAS); if (pAdidasShoes != NULL) { // 阿迪达斯球鞋广告喊起 pAdidasShoes->Show(); // 释放资源 delete pAdidasShoes; pAdidasShoes = NULL; } return 0; }
main
函数,先是构造了工厂对象,后创建指定类型的具体鞋子产品对象,创建了具体鞋子产品的对象便可直接打印广告。因为采用的是new
的方式创建了对象,用完了要通过delete
释放资源资源哦!
运行结果:
我是耐克球鞋,我的广告语:Just do it 我是李宁球鞋,我的广告语:Everything is possible 我是阿迪达斯球鞋,我的广告语:Impossible is nothing
鞋子买多了,你赚了大钱,想扩大生产线,多办几个工厂,每个工厂只生产一种鞋子,这样产量就大大的增加了,钱也赚的更多了。
#includeusing namespace std; class Shoes { public: virtual ~Shoes() {} virtual void Show() = 0; }; // 耐克鞋子 class NiKeShoes : public Shoes { public: void Show() { std::cout << "我是耐克球鞋,我的广告语:Just do it" << std::endl; } }; // 阿迪达斯鞋子 class AdidasShoes : public Shoes { public: void Show() { std::cout << "我是阿迪达斯球鞋,我的广告语:Impossible is nothing" << std::endl; } }; // 李宁鞋子 class LiNingShoes : public Shoes { public: void Show() { std::cout << "我是李宁球鞋,我的广告语:Everything is possible" << std::endl; } }; // 总鞋厂 class ShoesFactory { public: virtual Shoes *CreateShoes() = 0; virtual ~ShoesFactory() {} }; // 耐克工厂 class NiKeFactory : public ShoesFactory { public: Shoes *CreateShoes() { return new NiKeShoes(); } }; // 阿迪工厂 class AdidasFactory : public ShoesFactory { public: Shoes *CreateShoes() { return new AdidasShoes(); } }; // 李宁工厂 class LiNingFactory : public ShoesFactory { public: Shoes *CreateShoes() { return new LiNingShoes(); } }; int main() { // 建立耐克工厂 ShoesFactory *niKeProducer = new NiKeFactory(); Shoes *nikeShoes = niKeProducer->CreateShoes(); // 耐克球鞋广告喊起 nikeShoes->Show(); // 释放资源 delete nikeShoes; delete niKeProducer; //建立阿迪工厂 ShoesFactory *adidasProducer = new AdidasFactory(); Shoes *adidasShoes = adidasProducer->CreateShoes(); // 阿迪达斯球鞋广喊起 adidasShoes->Show(); // 释放资源 delete adidasShoes; delete adidasProducer; return 0; }
运行结果:
我是耐克球鞋,我的广告语:Just do it 我是阿迪达斯球鞋,我的广告语:Impossible is nothing
经过市场调查你发现,很多人喜欢穿一套,穿了耐克鞋子,那么得有耐克的衣服来配,好赚大钱的机会来了,鞋厂扩大了业务,不仅只生产鞋子,把运动品牌的衣服也一起生产了。
抽象工厂模式的特点:
提供一个接口,可以创建多个产品族中的产品对象。如创建耐克工厂,则可以创建耐克鞋子产品、衣服产品、裤子产品等。
抽象工厂模式的缺陷:
同工厂方法模式一样,新增产品时,都需要增加一个对应的产品的具体工厂类。
代码如下:
#includeusing namespace std; // 基类 衣服 class Clothe { public: virtual void Show() = 0; virtual ~Clothe() {} }; // 耐克衣服 class NiKeClothe : public Clothe { public: void Show() { std::cout << "我是耐克衣服,时尚我最在行!" << std::endl; } }; // 基类 鞋子 class Shoes { public: virtual void Show() = 0; virtual ~Shoes() {} }; // 耐克鞋子 class NiKeShoes : public Shoes { public: void Show() { std::cout << "我是耐克球鞋,让你酷起来!" << std::endl; } }; // 总厂 class Factory { public: virtual Shoes *CreateShoes() = 0; virtual Clothe *CreateClothe() = 0; virtual ~Factory() {} }; // 耐克生产者/生产链 class NiKeFactory : public Factory { public: Shoes *CreateShoes() { return new NiKeShoes(); } Clothe *CreateClothe() { return new NiKeClothe(); } }; int main() { // 建立耐克工厂 Factory *niKeProducer = new NiKeFactory(); // 耐克生产线产出球鞋 Shoes *nikeShoes = niKeProducer->CreateShoes(); // 耐克生产线产出衣服 Clothe *nikeClothe = niKeProducer->CreateClothe(); // 耐克球鞋广告喊起 nikeShoes->Show(); // 耐克衣服广告喊起 nikeClothe->Show(); // 释放资源 delete nikeShoes; delete nikeClothe; delete niKeProducer; return 0; }
运行结果:
我是耐克球鞋,让你酷起来! 我是耐克衣服,时尚我最在行!
以上三种工厂模式,在新增产品时,都存在一定的缺陷。
简单工厂模式,,需要去修改工厂类,这违背了开闭法则。
工厂方式模式和抽象工厂模式,都需要增加一个对应的产品的具体工厂类,这就会增大了代码的编写量。
那么有什么好的方法,在新增产品时,即不用修改工厂类,也不用新增具体的工厂类?