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

相关内容

热门资讯

安卓系统和oppo系统哪个流畅... 你有没有想过,手机系统哪个更流畅呢?安卓系统和OPPO系统,这两个名字听起来就让人心动。今天,咱们就...
安卓怎么用微软系统,利用微软系... 你是不是也和我一样,对安卓手机上的微软系统充满了好奇?想象那熟悉的Windows界面在你的安卓手机上...
安卓系统如何安装nfc,安卓系... 你有没有想过,用手机刷公交卡、支付账单,是不是比掏出钱包来得酷炫多了?这就得归功于NFC技术啦!今天...
ios系统可以转安卓,跨平台应... 你有没有想过,你的iPhone手机里的那些宝贝应用,能不能搬到安卓手机上继续使用呢?没错,今天就要来...
iOSapp移植到安卓系统,i... 你有没有想过,那些在iOS上让你爱不释手的app,是不是也能在安卓系统上大放异彩呢?今天,就让我带你...
现在安卓随便换系统,探索个性化... 你知道吗?现在安卓手机换系统简直就像换衣服一样简单!没错,就是那种随时随地、随心所欲的感觉。今天,就...
安卓系统安装按钮灰色,探究原因... 最近发现了一个让人头疼的小问题,那就是安卓手机的安装按钮突然变成了灰色,这可真是让人摸不着头脑。你知...
安卓7.1.1操作系统,系统特... 你知道吗?最近我在手机上发现了一个超级酷的新玩意儿——安卓7.1.1操作系统!这可不是什么小打小闹的...
安卓os系统怎么设置,并使用`... 你有没有发现,你的安卓手机有时候就像一个不听话的小孩子,有时候设置起来真是让人头疼呢?别急,今天就来...
安卓降低系统版本5.1,探索安... 你知道吗?最近安卓系统又来了一次大动作,竟然把系统版本给降到了5.1!这可真是让人有点摸不着头脑,不...
解放安卓系统被保护,解放安卓系... 你有没有想过,你的安卓手机其实可以更加自由地呼吸呢?是的,你没听错,我说的就是解放安卓系统被保护的束...
校务帮安卓系统下载,便捷校园生... 你有没有想过,你的手机里装了一个神奇的助手——校务帮安卓系统下载?没错,就是那个能让你轻松管理学校事...
安卓系统没有拼多多,拼多多崛起... 你知道吗?最近我在手机上发现了一个小小的秘密,那就是安卓系统里竟然没有拼多多这个应用!这可真是让我大...
甜城麻将安卓系统,解锁全新麻将... 你有没有听说过那个超级火的甜城麻将安卓系统?没错,就是那个让无数麻将爱好者为之疯狂的软件!今天,就让...
安卓系统卸载的软件,深度揭秘卸... 手机里的软件越来越多,是不是感觉内存不够用了?别急,今天就来教你怎么在安卓系统里卸载那些不再需要的软...
安卓系统推荐好游戏,畅享指尖乐... 手机里的游戏可是咱们休闲娱乐的好伙伴,尤其是安卓系统的用户,选择面那可是相当广呢!今天,就让我来给你...
王者安卓系统怎么卖,揭秘如何轻... 你有没有听说最近王者安卓系统的火爆程度?没错,就是那个让无数玩家沉迷其中的王者荣耀!今天,我就来给你...
安卓开发系统内置证书,基于安卓... 你有没有想过,你的安卓手机里那些神秘的内置证书,它们到底是个啥玩意儿?别急,今天就来给你揭秘这些隐藏...
荣耀安装安卓原生系统,深度体验... 你知道吗?最近荣耀手机界可是掀起了一股热潮,那就是——荣耀安装安卓原生系统!这可不是什么小打小闹,而...
安卓13小米系统,创新功能与流... 你知道吗?最近安卓13系统可谓是风头无两,各大手机厂商纷纷推出自家的新版系统,其中小米的安卓13系统...