C++设计模式之抽象工厂模式
创始人
2025-05-31 00:39:58
0

之前讲到了C++设计模式——工厂方法模式,我们可能会想到,后期产品会越来越多了,建立的工厂也会越来越多,工厂进行了增长,工厂变的凌乱而难于管理;而且由于工厂方法模式创建的对象都是继承于Product的,所以工厂方法模式中,每个工厂只能创建同一产品族的产品,当需要生产一种全新的产品(不继承自Product)时,发现工厂方法是心有余而力不足。

因此抽象工厂模式应运而生

UML类图:

现在要讲的抽象工厂模式,就是工厂方法模式的扩展和延伸,但是抽象工厂模式,更有一般性和代表性;它具有工厂方法具有的优点,也增加了解决实际问题的能力。
在这里插入图片描述

抽象工厂模式的通用源码类图:

在这里插入图片描述

注意类图上的圈圈、框框相对应,两个抽象的产品类可以有关系,例如共同继承或实现一个抽象类或接口。

#include 
using namespace std;// Product A
class ProductA
{
public:virtual void Show() = 0;
};class ProductA1 : public ProductA
{
public:void Show(){cout<<"I'm ProductA1"<
public:void Show(){cout<<"I'm ProductA2"<
public:virtual void Show() = 0;
};class ProductB1 : public ProductB
{
public:void Show(){cout<<"I'm ProductB1"<
public:void Show(){cout<<"I'm ProductB2"<
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;}
}

有N个产品族,在抽象工厂类中就应该有N个创建方法,比如有A、B,两个产品族,就要创建两个方法用于创建A、B两个产品族的对象,至于具体创建的是产品族中哪一个产品的对象,则结合业务情况进行分析,比如A产品族有A1、A2 两个产品,B产品族有B1、B2两个产品,抽象工厂类中的两个方法分别是创建A产品族对象和B产品族对象的,创建A产品族对象的方法到底是创建A1还是A2,创建B产品族对象的方法到底是创建B1还是B2,这是要结合实际业务情况进行分析的。

有M条生产线就应该实现M个实现工厂类,在每个实现工厂中,实现不同产品族的生产任务。就比如创建A1、B1是一条生产线,创建A2、B2是一条生产线,那就需要两个实现工厂类,第一个实现工厂类中创建A1、B1,第二个实现工厂类中创建A2、B2。

下面通过女娲造人来更加深入地理解抽象工厂模式,具体代码如下:

#include 
using namespace std;//多个产品族共同基础Human类
class Human
{
public://每个人种都有相应的颜色virtual void getColor() = 0;//人类会说话virtual void talk() = 0;//每个人都有性别virtual void getSex() = 0;
};//这里有3个产品族,分别是黄色人种、白色人种和黑色人种
class YellowHuman : public Human
{
public:void getColor(){cout << "黄种人的颜色是黄色的" << endl;}void talk(){cout << "黄种人说话一般是双字节" << endl;}
};class WhiteHuman :public Human
{
public:void getColor(){cout << "白种人的颜色是白色的" << endl;}void talk(){cout << "白种人说话一般是单字节" << endl;}
};class BlackHuman :public Human
{
public:void getColor(){cout << "黑种人的颜色是黑色的" << endl;}void talk(){cout << "黑种人说话一般人听不懂" << endl;}
};//产品族创建完毕后开始创建具体产品,每个产品族有两个产品
class YellowFemale:public YellowHuman
{
public:void getSex(){cout << "这是一个黄人女性" << endl;}
};class YellowMale :public YellowHuman
{
public:void getSex(){cout << "这是一个黄人男性" << endl;}
};class WhiteFemale :public WhiteHuman
{
public:void getSex(){cout << "这是一个白人女性" << endl;}
};class WhiteMale :public WhiteHuman
{
public:void getSex(){cout << "这是一个白人男性" << endl;}
};class BlackFemale :public BlackHuman
{
public:void getSex(){cout << "这是一个黑人女性" << endl;}
};class BlackMale :public BlackHuman
{
public:void getSex(){cout << "这是一个黑人男性" << endl;}
};//创建一个抽象工厂类
//有3个产品族,因此抽象工厂类需要有3个方法,分别创建不同产品族的某个产品的对象
class HumanFactory
{
public://创建一个黄种人virtual Human* createYellow() = 0;//创建一个白种人virtual Human* createWhite() = 0;//创建一个黑种人virtual Human* createBlack() = 0;
};//有两条生产线,创建女人和男人,因此有两个工厂实现类
//创建女人工厂实现类
class FemaleFactory :public HumanFactory
{
public:Human* createYellow(){//创建黄人女性return new YellowFemale();}Human* createWhite(){//创建白人女性return new WhiteFemale();}Human* createBlack(){//创建黑人女性return new BlackFemale();}
};//创建男人实现工厂类
class MaleFactory :public HumanFactory
{
public:Human* createYellow(){//创建黄人男性return new YellowMale();}Human* createWhite(){//创建白人男性return new WhiteMale();}Human* createBlack(){//创建黑人男性return new BlackMale();}
};int main()
{HumanFactory* maleFactory = new MaleFactory();HumanFactory* femaleFactory = new FemaleFactory();//工厂建立完毕,开始生产人//创建一个黄人男性Human* yellowMale = maleFactory->createYellow();//创建一个黄人女性Human* yellowFemale = femaleFactory->createYellow();yellowMale->getColor();yellowMale->getSex();yellowMale->talk();yellowFemale->talk();yellowFemale->getColor();yellowFemale->getSex();return 0;if(yellowMale != NULL){delete yellowMale;yellowMale = NULL;}if(yellowFemale != NULL){delete yellowFemale;yellowFemale = NULL;}}

抽象工厂模式的优点:

  • 封装性,每个产品的实现类不是高层模块要关心的,它要关心的是什么?是接口,是抽象,它不关心对象是如何创建出来,这由谁负责呢?工厂类,只要知道工厂类是谁,我就能创建出一个需要的对象,省时省力,优秀设计就应该如此。
  • 产品族内的约束为非公开状态。例如生产男女比例的问题上,猜想女娲娘娘肯定有自己的打算,不能让女盛男衰,否则女性的优点不就体现不出来了吗?那在抽象工厂模式,就应该有这样的一个约束:每生产1个女性,就同时生产出1.2个男性,这样的生产过程对调用工厂类的高层模块来说是透明的,它不需要知道这个约束,我就是要一个黄色女性产品就可以了,具体的产品族内的约束是在工厂内实现的。

抽象工厂模式的缺点:

抽象工厂模式的最大缺点就是产品族扩展非常困难,为什么这么说呢?我们以最开始的通用代码为例,如果要增加一个产品C,也就是说产品家族由原来的2个增加到3个,看看我们的程序有多大改动吧!抽象类AbstractCreator要增加一个方法createProductC(),然后两个实现类都要修改,想想看,这严重违反了开闭原则,而且我们一直说明抽象类和接口是一个契约。改变契约,所有与契约有关系的代码都要修改,那么这段代码叫什么?叫“有毒代码”,——只要与这段代码有关系,就可能产生侵害的危险!

适用场合:

工厂方法模式适用于产品种类结构单一的场合,为一类产品提供创建的接口;而抽象工厂方法适用于产品种类结构多的场合,主要用于创建一组不同产品族却彼此相关的产品,为它们提供创建的接口;就是当具有多个抽象角色时,抽象工厂便可以派上用场。

参考资料:

  • 《设计模式之禅》
  • https://www.cnblogs.com/ring1992/p/9592713.html

相关内容

热门资讯

电视安卓系统哪个品牌好,哪家品... 你有没有想过,家里的电视是不是该升级换代了呢?现在市面上电视品牌琳琅满目,各种操作系统也是让人眼花缭...
安卓会员管理系统怎么用,提升服... 你有没有想过,手机里那些你爱不释手的APP,背后其实有个强大的会员管理系统在默默支持呢?没错,就是那...
安卓系统软件使用技巧,解锁软件... 你有没有发现,用安卓手机的时候,总有一些小技巧能让你玩得更溜?别小看了这些小细节,它们可是能让你的手...
安卓系统提示音替换 你知道吗?手机里那个时不时响起的提示音,有时候真的能让人心情大好,有时候又让人抓狂不已。今天,就让我...
安卓开机不了系统更新 手机突然开不了机,系统更新还卡在那里,这可真是让人头疼的问题啊!你是不是也遇到了这种情况?别急,今天...
安卓系统中微信视频,安卓系统下... 你有没有发现,现在用手机聊天,视频通话简直成了标配!尤其是咱们安卓系统的小伙伴们,微信视频功能更是用...
安卓系统是服务器,服务器端的智... 你知道吗?在科技的世界里,安卓系统可是个超级明星呢!它不仅仅是个手机操作系统,竟然还能成为服务器的得...
pc电脑安卓系统下载软件,轻松... 你有没有想过,你的PC电脑上安装了安卓系统,是不是瞬间觉得世界都大不一样了呢?没错,就是那种“一机在...
电影院购票系统安卓,便捷观影新... 你有没有想过,在繁忙的生活中,一部好电影就像是一剂强心针,能瞬间让你放松心情?而我今天要和你分享的,...
安卓系统可以写程序? 你有没有想过,安卓系统竟然也能写程序呢?没错,你没听错!这个我们日常使用的智能手机操作系统,竟然有着...
安卓系统架构书籍推荐,权威书籍... 你有没有想过,想要深入了解安卓系统架构,却不知道从何下手?别急,今天我就要给你推荐几本超级实用的书籍...
安卓系统看到的炸弹,技术解析与... 安卓系统看到的炸弹——揭秘手机中的隐形威胁在数字化时代,智能手机已经成为我们生活中不可或缺的一部分。...
鸿蒙系统有安卓文件,畅享多平台... 你知道吗?最近在科技圈里,有个大新闻可是闹得沸沸扬扬的,那就是鸿蒙系统竟然有了安卓文件!是不是觉得有...
宝马安卓车机系统切换,驾驭未来... 你有没有发现,现在的汽车越来越智能了?尤其是那些豪华品牌,比如宝马,它们的内饰里那个大屏幕,简直就像...
p30退回安卓系统 你有没有听说最近P30的用户们都在忙活一件大事?没错,就是他们的手机要退回安卓系统啦!这可不是一个简...
oppoa57安卓原生系统,原... 你有没有发现,最近OPPO A57这款手机在安卓原生系统上的表现真是让人眼前一亮呢?今天,就让我带你...
安卓系统输入法联想,安卓系统输... 你有没有发现,手机上的输入法真的是个神奇的小助手呢?尤其是安卓系统的输入法,简直就是智能生活的点睛之...
怎么进入安卓刷机系统,安卓刷机... 亲爱的手机控们,你是否曾对安卓手机的刷机系统充满好奇?想要解锁手机潜能,体验全新的系统魅力?别急,今...
安卓系统程序有病毒 你知道吗?在这个数字化时代,手机已经成了我们生活中不可或缺的好伙伴。但是,你知道吗?即使是安卓系统,...
奥迪中控安卓系统下载,畅享智能... 你有没有发现,现在汽车的中控系统越来越智能了?尤其是奥迪这种豪华品牌,他们的中控系统简直就是科技与艺...