【UE4 设计模式】抽象工厂模式 Abstract Factory Pattern
概述
描述
提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类;具体的工厂负责实现具体的产品实例
抽象工厂中每个工厂可以创建多种产品(如苹果公司生产iPhone、iPad);
工厂方法每个工厂只能创建一种
三种工厂小结
假设有骷髅士兵、骷髅弓箭手、哥布林士兵、哥布林弓箭手四种怪物
- 简单工厂模式
一个工厂有四个方法创建骷髅士兵、骷髅弓箭手、哥布林士兵、哥布林弓箭手 - 工厂方法模式
四个工厂: 骷髅士兵工厂、骷髅弓箭手工厂、哥布林士兵工厂、哥布林弓箭手工厂,每个工厂创建对应的怪物 - 抽象工厂模式
两个工厂: 骷髅怪物工厂 负责创建骷髅士兵、骷髅弓箭手;哥布林工厂,负责创建困难哥布林士兵、哥布林弓箭手。
套路
- 创建抽象产品族类 ,定义抽象产品的公共接口;
- 创建抽象产品类 ,继承抽象产品族类;(此处可理解为相对具体得产品族类)
- 创建具体产品类,继承抽象产品类;
- 创建抽象工厂类
- 创建工厂类,继承抽象工厂类,定义具体产品类的创建方法;
- 通过调用具体工厂类的方法,从而创建不同具体产品类的实例
使用场景
- 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有类型的工厂模式都是重要的。
- 系统中有多个产品族,每次只使用其中某一产品族。
- 属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来。
- 系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。
- 举例
- 敌人生成,不同区域地点可以利用不同工厂生成不同敌人,
- 游戏难度,不同难度可以产生不同类型的建筑、英雄以及技能。
- AI 战术选择。实现确定好几种可选战术作为产品族,每种战术按照类似海军、空军、陆军作为产品等级结构选择具体兵种进行生产建造。
- 多语言。用户改变语言环境时,会改变响应的文字显示,音效,图片显示,操作习惯适配等。
- 皮肤更换或者资源管理。用户选择不同主题的皮肤将会影响图片显示以及动画效果。
- 屏幕适配。对高、中、低分辨率的移动设备使用不同的显示资源。
优缺点
- 优点
- 隔离了具体类的生成,使得调用者不需要知道什么被创建。所有的具体工厂都实现了抽象工厂中定义的那些公共接口,因此只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。实现了高内聚低耦合
- 所有的具体工厂都实现了抽象工厂中定义的那些公共接口,因此只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。
- 增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。
- 缺点
- 在添加新的产品对象时,难以扩展抽象工厂来生产新种类的产品,这是因为在抽象工厂角色中规定了所有可能被创建的产品集合,要支持新种类的产品就意味着要对该接口进行扩展,而这将涉及到对抽象工厂角色及其所有子类的修改,显然会带来较大的不便。
- 开闭原则的倾斜性(增加新的工厂和产品族容易,增加新的产品等级结构麻烦)。
UE4 实践
做一个简单得怪物生成器,在不死族地带生成不死族怪物,在哥布林地带生成哥布林怪物;怪物分别有士兵和弓箭手两种
创建抽象产品族类、抽象产品类——怪物、怪物士兵、怪物弓箭手
// 抽象产品族类 —— 怪物
UCLASS(Abstract)
class DESIGNPATTERNS_API UMonster : public UObject
{
GENERATED_BODY()
public:
virtual void ShowInfo() { check(0 && "You must override this"); }
}; // 抽象产品类、具体产品族 —— 怪物士兵
UCLASS(Blueprintable, BlueprintType)
class DESIGNPATTERNS_API UMonsterSoldier : public UMonster
{
GENERATED_BODY()
public:
virtual void ShowInfo() override {
UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" This is a Monster Soldier"));
}
}; // 抽象产品类、具体产品族 —— 怪物弓箭手
UCLASS(Blueprintable, BlueprintType)
class DESIGNPATTERNS_API UMonsterArcher : public UMonster
{
GENERATED_BODY()
public:
virtual void ShowInfo() override {
UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" This is a Monster Archer"));
}
};
创建具体产品类——骷髅士兵、骷髅弓箭手、哥布林士兵、哥布林弓箭手
// 具体产品类 —— 怪物士兵 —— 骷髅士兵
UCLASS(Blueprintable, BlueprintType)
class DESIGNPATTERNS_API UUndeadSkeletonSoldier : public UMonsterSoldier
{
GENERATED_BODY()
public:
virtual void ShowInfo() override {
UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" This is a Undead Skeleton Soldier"));
}
}; // 具体产品类 —— 怪物士兵 —— 哥布林士兵
UCLASS(Blueprintable, BlueprintType)
class DESIGNPATTERNS_API UGoblinSoldier : public UMonsterSoldier
{
GENERATED_BODY()
public:
virtual void ShowInfo() override {
UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" This is a Goblin Soldier"));
}
}; // 具体产品类 —— 怪物弓箭手 —— 骷髅弓箭手
UCLASS(Blueprintable, BlueprintType)
class DESIGNPATTERNS_API UUndeadSkeletonArcher : public UMonsterArcher
{
GENERATED_BODY()
public:
virtual void ShowInfo() override {
UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" This is a Undead Skeleton Archer"));
}
}; // 具体产品类 —— 怪物弓箭手 —— 哥布林弓箭手
UCLASS(Blueprintable, BlueprintType)
class DESIGNPATTERNS_API UGoblinArcher : public UMonsterArcher
{
GENERATED_BODY()
public:
virtual void ShowInfo() override {
UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" This is a Goblin Archer"));
}
};
创建抽象工厂类、具体工厂类——怪物生成器、不死族怪物生成器、哥布林怪物生成器
// 抽象工厂类 —— 怪物生成器
UCLASS(Abstract)
class DESIGNPATTERNS_API UMonsterFactory : public UObject
{
GENERATED_BODY()
public: // 生成士兵
virtual UMonsterSoldier* CreateMonsterSoldier() {
check(0 && "You must override this");
return nullptr;
} // 生成弓箭手
virtual UMonsterArcher* CreateMonsterArcher(){
check(0 && "You must override this");
return nullptr;
} }; // 具体工厂类 —— 不死族怪物生成器
UCLASS(Blueprintable, BlueprintType)
class DESIGNPATTERNS_API UUndeadMonsterFactory : public UMonsterFactory
{
GENERATED_BODY()
public:
// 生成骷髅士兵
virtual UMonsterSoldier* CreateMonsterSoldier() override {
return NewObject<UUndeadSkeletonSoldier>(); // 实际使用 SpawnActor
} // 生成骷髅弓箭手
virtual UMonsterArcher* CreateMonsterArcher() override {
return NewObject<UUndeadSkeletonArcher>();
}
}; // 具体工厂类 —— 哥布林怪物生成器
UCLASS(Blueprintable, BlueprintType)
class DESIGNPATTERNS_API UGoblinMonsterFactory : public UMonsterFactory
{
GENERATED_BODY()
public: // 生成哥布林士兵
virtual UMonsterSoldier* CreateMonsterSoldier() override {
return NewObject<UGoblinSoldier>(); // 实际使用 SpawnActor
} // 生成哥布林弓箭手
virtual UMonsterArcher* CreateMonsterArcher() override {
return NewObject<UGoblinArcher>();
}
};
测试调用
// 调用测试用的Actor
UCLASS()
class DESIGNPATTERNS_API AMonsterGenerator : public AActor
{
GENERATED_BODY()
public: void BeginPlay() override { // 不死族地带区域 生成怪物
UUndeadMonsterFactory* UndeadMonsterFactory = NewObject<UUndeadMonsterFactory>();
UndeadMonsterFactory->CreateMonsterSoldier()->ShowInfo();
UndeadMonsterFactory->CreateMonsterArcher()->ShowInfo(); // 哥布林地带生成 怪物
UGoblinMonsterFactory* GoblinMonsterFactory = NewObject<UGoblinMonsterFactory>();
GoblinMonsterFactory->CreateMonsterSoldier()->ShowInfo();
GoblinMonsterFactory->CreateMonsterArcher()->ShowInfo();
}
};
调式输出
LogTemp: Warning: UUndeadSkeletonSoldier::ShowInfo This is a Undead Skeleton Soldier
LogTemp: Warning: UUndeadSkeletonArcher::ShowInfo This is a Undead Skeleton Archer
LogTemp: Warning: UGoblinSoldier::ShowInfo This is a Goblin Soldier
LogTemp: Warning: UGoblinArcher::ShowInfo This is a Goblin Archer
参考
【UE4 设计模式】抽象工厂模式 Abstract Factory Pattern的更多相关文章
- 设计模式 - 抽象工厂模式(abstract factory pattern) 具体解释
抽象工厂模式(abstract factory pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/2709 ...
- C#设计模式——抽象工厂模式(Abstract Factory Pattern)
一.概述在软件开发中,常常会需要创建一系列相互依赖的对象,同时,由于需求的变化,往往存在较多系列对象的创建工作.如果采用常规的创建方法(new),会造成客户程序和对象创建工作的紧耦合.对此,抽象工厂模 ...
- 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern)
原文:乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factor ...
- 【设计模式】抽象工厂模式 Abstract Factory Pattern
简单工厂模式是一个工厂类根据工厂方法的参数创建不出不同的产品, 工厂方法模式是每一个产品都有一个一一对应的工厂负责创建该产品.那么今天要讲的抽象工厂模式是一个工厂能够产生关联的一系列产品.抽象工厂模式 ...
- 二十四种设计模式:抽象工厂模式(Abstract Factory Pattern)
抽象工厂模式(Abstract Factory Pattern) 介绍提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 示例有Message和MessageModel,Messag ...
- 设计模式之抽象工厂模式(Abstract Factory Pattern)
一.抽象工厂模式的由来 抽象工厂模式,最开始是为了解决操作系统按钮和窗体风格,而产生的一种设计模式.例如:在windows系统中,我们要用windows设定的按钮和窗体,当我们切换Linux系统时,要 ...
- Net设计模式实例之抽象工厂模式(Abstract Factory Pattern)
一.抽象工厂模式简介(Bref Introduction) 抽象工厂模式(Abstract Factory Pattern),提供一个创建一系列相关或者相互依赖对象的接口,而无需制定他们的具体类.优点 ...
- Objective-C设计模式——抽象工厂模式Abstract Factory(对象创建)
抽象工厂模式 理解了工厂方法模式,其实抽象工厂和工厂方法模式有很多的相似之处.抽象工厂同样是分离客户端对象的创建和逻辑代码的,但是抽象工厂往往是产生一组数据而不单单是产生一个产品. 抽象工厂提供一个创 ...
- 六个创建模式之抽象工厂模式(Abstract Factory Pattern)
问题: 使用工厂方法模式的主要问题是工厂类过多,每个产品对应一个工厂,不利于维护.因此可以考虑使用一个工厂创建一个产品族. 定义: 提供创建一些列相关或相互依赖的对象实例的接口,这些类可以称为一个产品 ...
随机推荐
- outerHTML和outerText的赋值是异步的
用JavaScript操作DOM时,经常有生成复杂HTML结构的需求.此时,通常不是用标准DOM接口(如createElement().setAttribute().append()等)来语句式地生成 ...
- MySQL高级语句(一)
一.MySQL高级进阶SQL 语句 1.SELECT 2.DISTINCT 3.WHERE 4.AND.OR 5.IN 6.BETWEEN 7.通配符.LIKE 8.ORDER BY 9.| | 连 ...
- 泛微OA E-cology(CNVD-2019-32204)远程命令执行漏洞复现分析
漏洞复现 影响版本: E-cology 7.0 E-cology 8.0 E-cology 8.1 E-cology 9.0 直接在网站根目录后加入组件访问路径 /weaver/bsh.servl ...
- shell中的$0 $n $# $* $@ $? $$
$0当前脚本的文件名 $n传递给脚本或函数的参数.n 是一个数字,表示第几个参数.例如,第一个参数是$1,第二个参数是$2. $#传递给脚本或函数的参数个数. $*传递给脚本或函数的所有参数. $@传 ...
- k8s 部署elasticsearch报 max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
1.由于登不上云的节点 不采用修改节点配置的方式 修改部署的stateful 加上 initContainers 它和 containers 同一层级的 initContainers: - name: ...
- VS Code + WSL 搭建 RaspberryPi Pico 开发环境
前面老周写一堆 .NET 与树莓派相关的水文.其实使用的是.net的 IOT 库,并不只是树莓派,其他运行 Linux 的开发板都适用,只要有 GPIO 就行.老周好像在哪看到过,有 USB 转GPI ...
- 建立 F103C8T6 HAL库 Makefile FreeRTOS 工程
F103C8T6 HAL库 Makefile FreeRTOS 工程模板 环境 该工程的开发平台为 ARM-GCC 工具链和 Make > arm-none-eabi-gcc -v gcc ve ...
- iNeuLink硬件网关与iNeuOS工业互联网操作系统互联互通应用案例
目 录 1. 应用概述... 2 2. 模拟硬件设备配置... 2 3. iNeuLink硬件网关配置... 4 3.1 硬件介绍... ...
- 学习PHP中统计扩展函数的使用
做统计相关系统的朋友一定都会学习过什么正态分布.方差.标准差之类的概念,在 PHP 中,也有相应的扩展函数是专门为这些统计相关的功能所开发的.我们今天要学习的 stats 扩展函数库就是这类操作函数. ...
- 在PHP中使用SPL库中的对象方法进行XML与数组的转换
虽说现在很多的服务提供商都会提供 JSON 接口供我们使用,但是,还是有不少的服务依然必须使用 XML 作为接口格式,这就需要我们来对 XML 格式的数据进行解析转换.而 PHP 中并没有像 json ...