设计模式(C++)-创建型模式-抽象工厂模式

一、抽象工厂模式概述

  • 分类:(对象)创建型
  • 问题:假如我们要买水果,水果的产地来自中国、日本、美国,每个国家的水果种类都可以分为苹果、香蕉、梨子。
    作为开发者,我们就不得不创建苹果类(香蕉和梨子类似),然后每种苹果都继承自苹果类。每上架一个国家
    的苹果我们都要实现一次苹果类,这样就会有成千上万的苹果类需要被创建,AbstractFactory 模式就是用来
    解决这类问题的:要创建一组相关或者相互依赖的对象
  • 解决方案:提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。

二、抽象工厂模式UML类图

抽象工厂模式

三、抽象工厂模式代码实现

#pragama once
class abstract_apple;
class abstract_banana;
class abstract_pear;

//抽象工厂 针对产品族
class abstract_factory {
public:
	virtual abstract_apple*  create_apple() = 0;
	virtual abstract_banana* create_banana() = 0;
	virtual abstract_pear*   create_pear() = 0;
};

//中国工厂
class china_factory :public abstract_factory {
public:
	abstract_apple*  create_apple() override;
	abstract_banana* create_banana() override;
	abstract_pear*   create_pear()override;
};

//美国工厂
class usa_factory :public abstract_factory {
public:
	abstract_apple*  create_apple() override;
	abstract_banana* create_banana() override;
	abstract_pear*   create_pear()override;
};

//日本工厂
class japan_factory :public abstract_factory {
public:
	abstract_apple*  create_apple() override;
	abstract_banana* create_banana() override;
	abstract_pear*   create_pear()override;
};

//abstract_factory.cpp
#include "abstract_factory.h"
#include "abstract_product.h"

//中国工厂
abstract_apple*  china_factory::create_apple() {
	return new china_apple;
}
abstract_banana* china_factory::create_banana() {
	return new china_banana;
}
abstract_pear*   china_factory::create_pear() {
	return new china_pear;
}

//美国工厂
abstract_apple*  usa_factory::create_apple() {
	return new usa_apple;
}
abstract_banana* usa_factory::create_banana() {
	return new usa_banana;
}
abstract_pear*   usa_factory::create_pear() {
	return new usa_pear;
}

//日本工厂
abstract_apple*  japan_factory::create_apple() {
	return new japan_apple;
}
abstract_banana* japan_factory::create_banana() {
	return new japan_banana;
}
abstract_pear*   japan_factory::create_pear() {
	return new japan_pear;
}
//abstract product
#pragma once
#include <iostream>
using namespace std;
//抽象苹果基类
class abstract_apple {
public:
	virtual void showName() = 0;
};
//中国苹果
class china_apple :public abstract_apple {
public:
	virtual void showName();
};

//美国苹果
class usa_apple :public abstract_apple {
public:
	virtual void showName();
};

//中国苹果
class japan_apple :public abstract_apple {
public:
	virtual void showName();
};

//抽象香蕉基类
class abstract_banana {
public:
	virtual void showName() = 0;
};
//中国香蕉
class china_banana :public abstract_banana {
public:
	virtual void showName();
};

//美国香蕉
class usa_banana :public abstract_banana {
public:
	virtual void showName();
};

//日本香蕉
class japan_banana :public abstract_banana {
public:
	virtual void showName();
};

class abstract_pear {
public:
	virtual void showName() = 0;
};

//中国鸭梨
class china_pear :public abstract_pear {
public:
	virtual void showName();
};

//美国鸭梨
class usa_pear :public abstract_pear {
public:
	virtual void showName();
};

//日本鸭梨
class japan_pear :public abstract_pear {
public:
	virtual void showName();
};

//抽象产品实现
#include "abstract_product.h"

void china_apple::showName(){
	cout << "中国苹果" << endl;
}
void usa_apple::showName() {
	cout << "美国苹果" << endl;
}
void japan_apple::showName() {
	cout << "日本苹果" << endl;
}

void china_banana::showName() {
	cout << "中国香蕉" << endl;
}
void usa_banana::showName() {
	cout << "美国香蕉" << endl;
}
void japan_banana::showName() {
	cout << "日本香蕉" << endl;
}

void china_pear::showName() {
	cout << "中国鸭梨" << endl;
}
void usa_pear::showName() {
	cout << "美国鸭梨" << endl;
}
void japan_pear::showName() {
	cout << "日本鸭梨" << endl;
}

//调用示例
void testAbstractFactory() {
	cout << "=====AbstractFactory Begin===================" << endl;
	abstract_factory* factory = nullptr;
	abstract_apple* apple = nullptr;
	abstract_banana* banana = nullptr;
	abstract_pear* pear = nullptr;

	factory = new china_factory;
	apple = factory->create_apple();
	banana = factory->create_banana();
	pear = factory->create_pear();

	apple->showName();
	banana->showName();
	pear->showName();

	delete pear;
	delete banana;
	delete apple;
	delete factory;


	factory = new usa_factory;
	apple = factory->create_apple();
	banana = factory->create_banana();
	pear = factory->create_pear();

	apple->showName();
	banana->showName();
	pear->showName();

	delete pear;
	delete banana;
	delete apple;
	delete factory;


	factory = new japan_factory;
	apple = factory->create_apple();
	banana = factory->create_banana();
	pear = factory->create_pear();

	apple->showName();
	banana->showName();
	pear->showName();

	delete pear;
	delete banana;
	delete apple;
	delete factory;
	cout << "=====AbstractFactory End===================" << endl;
}

四、优缺点总结

1.核心优势

  1. 保证产品族的完整性与一致性
    模式强制同一工厂生产的产品属于同一个系列(如全套ios控件或全套Windows控件),防止“Mac窗口+Win按钮”的错误组合,极大降低了配置错乱风险
  2. 彻底隔离客户端与具体实现
    客户端仅依赖抽象接口(AbstractFactory/AbstractProduct),更换产品线(如从Android转换为HarmonyOS组件)只需替换具体工厂实例,无需要改动任何业务逻辑代码,天然支持“配置话切换”
  3. 强化开闭原则
    新增同系列产品族只需要添加新的具体工厂类,不对已有代码产生侵入,利于多品牌、多平台平行迭代。

2.局限与代价

  1. 纵向扩展成本高昂(违反开闭原则另一面)
    如需要在现有产品族中增加一个新种类的产品(如原来只有Button/Text,现需要增加Slider),必须修改抽象工厂接口及其所有派生类实现,波及范围广,扩展成本和现有子类数量成正比。
    2.过度设计风险显著
    对于仅需单个产品独立变化的场景(如只需换按钮样式),该模式引入了不必要的“簇约束”和层级复杂度,反而增加了维护负担。
    3.代码冗长与理解难度
    每套产品族需配套完整的类层级,在小规模项目中会导致文件激增,逻辑跳转加深,新人上手成本高。
Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐