当前位置: 首页 > Linux

C++工厂模式详解(初学者)

时间:2023-04-06 06:48:14 Linux

初看工厂模式先来看看工厂模式的介绍这类设计模式是一种创建型模式,它提供了创建对象的最佳方式。在工厂模式下,我们在创建对象时不向客户端暴露创建逻辑,而是使用一个通用的接口指向新创建的对象。简单来说,就是利用C++的多态特性,利用一个具有继承关系的类,通过一个工厂类创建对应的子类(派生类)对象。在项目复杂的情况下,可以方便创建子类对象。工厂模式的实现可以分为简单工厂模式、工厂方法模式和抽象工厂模式,它们各有优缺点。最近炒鞋很火,所以以鞋厂的形式,对每一种实现方式一一进行分析。简易工厂模式的具体情况:鞋厂可以指定生产耐克、阿迪达斯、李宁品牌的鞋。哪款鞋流行,老板就视情况生产哪款。UML图:简单工厂模式的结构组成:工厂类(ShoesFactory):工厂模式的核心类,它定义了一个接口,用于创建指定的具体实例对象。抽象产品类(Shoes):是具体产品类的继承父类或实现的接口。具体产品类(NiKeShoes\AdidasShoes\LiNingShoes):工厂类创建的对象就是这个具体的产品实例。简单工厂模式的特点:工厂类封装了创建具体产品对象的功能。简单工厂模式的缺陷:可扩展性很差。添加新产品时,需要修改工厂类。简单工厂模式的代码:Shoes是鞋子的抽象类(基类),接口函数为Show(),用于展示鞋子广告。NikeShoes、AdidasShoes、LiNingShoes是具体的鞋类,分别是Nike、Adidas、Li-Ning鞋类,都继承自Shoes抽象类。//ShoesabstractclassShoes{public:virtual~Shoes(){}virtualvoidShow()=0;};//NikeshoesclassNiKeShoes:publicShoes{public:voidShow(){std::cout<<"我是耐克运动鞋,我的口号:Justdoit"<Show();//释放资源deletepNikeShoes;pNikeShoes=NULL;}//从鞋厂对象Shoes*pLiNingShoes=shoesFactory.CreateShoes(LINING)创建阿迪达斯鞋对象if(pLiNingShoes!=NULL){//李宁运动鞋广告调用pLiNingShoes->Show();//释放资源deletepLiNingShoes;pLiNingShoes=NULL;}//从鞋厂对象Shoes*pAdidasShoes=shoesFactory.CreateShoes(ADIDAS);创建Adidas鞋对象if(pAdidasShoes!=NULL){//阿迪达斯运动鞋广告调用pAdidasShoes->Show();//释放资源deletepAdidasShoes;pAdidasShoes=NULL;}return0;}输出结果:[root@lincodingfactory]#./simpleFactory我是耐克运动鞋,我的口号:Justdoit我是阿迪达斯运动鞋,我的口号:Impossibleisnothing我是李宁运动鞋,我的口号:Everything是拥有ible工厂方法模式的具体情况:现在各种鞋子都很流行,所以要想批量生产每一种鞋子,就需要针对不同品牌的鞋子,建立独立的生产线,那么每条生产线就可以只生产同类型品牌。鞋子UML图:工厂方法模式的结构组成:抽象工厂类工厂(ShoesFactory):工厂方法模式的核心类,提供创建具体产品的接口,由具体的工厂类实现。具体工厂类(NiKeProducer\AdidasProducer\LiNingProducer):继承于抽象工厂,实现创建相应具体产品对象的方式。抽象产品类(Shoes):是具体产品继承的父类(基类)。具体产品类(NikeShoes\AdidasShoes\LiNingShoes):具体工厂创建的对象就是这个类。工厂方法模式的特点:工厂方法模式将工厂类抽象出来,提供创建具体产品的接口,子类实现。工厂方法模式的应用不仅仅是封装具体产品对象的创建,而是在具体的工厂类中实现具体产品对象的创建。工厂方法模式的缺陷:每增加一个新的产品,都需要添加对应产品的具体工厂类。工厂方法模式比简单工厂模式需要更多的类定义。一条生产线只能有一个产品。工厂方法模式的代码:ShoesFactory抽象工厂类提供纯虚函数,用于创建具体的鞋类产品。NikeProducer、AdidasProducer、LiNingProducer具体工厂类继承连续工厂类,实现对应具体鞋类产品对象的创建。//总鞋厂类ShoesFactory{public:virtualShoes*CreateShoes()=0;virtual~ShoesFactory(){}};//耐克生产商/生产链类NiKeProducer:publicShoesFactory{public:Shoes*CreateShoes(){returnnewNiKeShoes();}};//阿迪达斯生产者/生产链类AdidasProducer:publicShoesFactory{public:Shoes*CreateShoes(){returnnewAdidasShoes();}};//李宁生产者/生产链类LiNingProducer:publicShoesFactory{public:Shoes*CreateShoes(){returnnewLiNingShoes();}};main函数为每一种鞋子构造每一种生产线,然后每条生产线生产对应的鞋子。需要注意的是,具体的工厂对象和具体的产品对象用完后需要通过delete释放资源。intmain(){//==================耐克生产流程=======================////鞋厂开启耐克生产线ShoesFactory*niKeProducer=newNiKeProducer();//Nike生产线生产运动鞋Shoes*nikeShoes=niKeProducer->CreateShoes();//耐克运动鞋广告调用nikeShoes->Show();//释放资源deletenikeShoes;删除niKeProducer;//=================阿迪达斯生产流程======================////鞋子工厂打开阿迪达斯生产商ShoesFactory*adidasProducer=newAdidasProducer();//Adidas生产线生产运动鞋Shoes*adidasShoes=adidasProducer->CreateShoes();//阿迪达斯运动鞋调用adidasShoes->Show();//释放资源deleteadidasShoes;删除adidasProducer;return0;}输出结果:[root@lincodingfactory]#./methodFactory我是耐克运动鞋,我的口号:Justdoit我是阿迪达斯运动鞋,我的口号:不可能是什么都没有抽象工厂模型的具体情况:为了为了扩大业务,鞋厂不仅生产鞋子,还生产运动品牌服装。UML图:抽象工厂模式的结构组成(同工厂方法模式):抽象工厂类工厂(ShoesFactory):工厂方法模式的核心类,提供创建具体产品的接口,由具体的工厂类。具体工厂类(NiKeProducer):继承于抽象工厂,实现了创建相应具体产品对象的方法。抽象商品类(Shoes\Clothe):是具体商品继承的父类(基类)。具体产品类(NiKeShoes\NiKeClothe):具体工厂创建的对象就是这个类。抽象工厂模式的特点:提供一个接口,可以在多个产品系列中创建产品对象。如果创建一个耐克工厂,就可以创建耐克鞋、衣服、裤子等。抽象工厂模式的缺陷:和工厂方法模式一样,在添加新产品时,需要为对应的产品添加具体的工厂类产品。抽象工厂接触代码:Clothe和Shoes,分别是衣服和鞋子的抽象产品类别。NiKeClothe和NiKeShoes分别是耐克服装和耐克服装的具体产品类别。//基类ClothesclassClothe{public:virtualvoidShow()=0;virtual~Clothe(){}};//NikeclothesclassNiKeClothe:publicClothe{public:voidShow(){std::cout<<"我是Nike,我擅长时尚!"<<标准::结束;}};//基类Shoes{public:virtualvoidShow()=0;虚拟~Shoes(){}};//耐克鞋类NiKeShoes:publicShoes{public:voidShow(){std::cout<<"我是耐克鞋,让你酷!"<<标准::结束;}};Factory是一个抽象工厂,提供创建鞋子CreateShoes()和服装产品CreateClothe()对象的接口。NikeProducer实现了为特定工厂制作耐克鞋和耐克衣服的方式。//一般工厂类Factory{public:virtualShoes*CreateShoes()=0;虚拟衣服*CreateClothe()=0;virtual~Factory(){}};//Nike生产者/生产链类NiKeProducer:publicFactory{public:Shoes*CreateShoes(){returnnewNiKeShoes();}Clothe*CreateClothe(){returnnewNiKeClothe();}};main函数,构造耐克工厂对象,通过耐克工厂对象鞋类对象重新制作耐克产品系列的衣服和衣服。同样,当对象不再使用时,需要手动释放资源。intmain(){//==================耐克生产流程=======================////鞋厂开启耐克生产线Factory*niKeProducer=newNiKeProducer();//Nike生产线生产运动鞋Shoes*nikeShoes=niKeProducer->CreateShoes();//Nike生产线生产衣服Clothes*nikeClothe=niKeProducer->CreateClothe();//耐克运动鞋广告调用nikeShoes->Show();//耐克服装广告调用nikeClothe->Show();//释放资源deletenikeShoes;删除耐克衣服;删除niKeProducer;return0;}输出结果:[root@lincodingfactory]#./abstractFactory我是耐克运动鞋,让你酷!我是耐克,我最擅长时尚!总结以上三种工厂模式,在添加新产品时都存在一定的缺陷。简单工厂模式需要修改工厂类,违反了开闭规律。工厂模式和抽象工厂模式都需要为对应的产品添加具体的工厂类,会增加代码编写量。那么在不修改工厂类或添加特定工厂类的情况下添加新产品的最佳方法是什么?笔者在实际项目中看到了一个封装性很强的工厂类。扩展新产品时,无需修改工厂类,也无需添加具体的工厂类。具体可以跳转到C++。步骤)阅读。