概述

描述

  • 提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类;具体的工厂负责实现具体的产品实例

  • 抽象工厂中每个工厂可以创建多种产品(如苹果公司生产iPhone、iPad);

    工厂方法每个工厂只能创建一种

三种工厂小结

假设有骷髅士兵、骷髅弓箭手、哥布林士兵、哥布林弓箭手四种怪物

  • 简单工厂模式

    一个工厂有四个方法创建骷髅士兵、骷髅弓箭手、哥布林士兵、哥布林弓箭手
  • 工厂方法模式

    四个工厂: 骷髅士兵工厂、骷髅弓箭手工厂、哥布林士兵工厂、哥布林弓箭手工厂,每个工厂创建对应的怪物
  • 抽象工厂模式

    两个工厂: 骷髅怪物工厂 负责创建骷髅士兵、骷髅弓箭手;哥布林工厂,负责创建困难哥布林士兵、哥布林弓箭手。

套路

  • 创建抽象产品族类 ,定义抽象产品的公共接口;
  • 创建抽象产品类 ,继承抽象产品族类;(此处可理解为相对具体得产品族类)
  • 创建具体产品类,继承抽象产品类;
  • 创建抽象工厂类
  • 创建工厂类,继承抽象工厂类,定义具体产品类的创建方法;
  • 通过调用具体工厂类的方法,从而创建不同具体产品类的实例

使用场景

  • 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有类型的工厂模式都是重要的。
  • 系统中有多个产品族,每次只使用其中某一产品族。
  • 属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来。
  • 系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。
  • 举例
    • 敌人生成,不同区域地点可以利用不同工厂生成不同敌人,
    • 游戏难度,不同难度可以产生不同类型的建筑、英雄以及技能。
    • AI 战术选择。实现确定好几种可选战术作为产品族,每种战术按照类似海军、空军、陆军作为产品等级结构选择具体兵种进行生产建造。
    • 多语言。用户改变语言环境时,会改变响应的文字显示,音效,图片显示,操作习惯适配等。
    • 皮肤更换或者资源管理。用户选择不同主题的皮肤将会影响图片显示以及动画效果。
    • 屏幕适配。对高、中、低分辨率的移动设备使用不同的显示资源。

优缺点

  • 优点

    • 隔离了具体类的生成,使得调用者不需要知道什么被创建。所有的具体工厂都实现了抽象工厂中定义的那些公共接口,因此只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。实现了高内聚低耦合
    • 所有的具体工厂都实现了抽象工厂中定义的那些公共接口,因此只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。
    • 增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。
  • 缺点
    • 在添加新的产品对象时,难以扩展抽象工厂来生产新种类的产品,这是因为在抽象工厂角色中规定了所有可能被创建的产品集合,要支持新种类的产品就意味着要对该接口进行扩展,而这将涉及到对抽象工厂角色及其所有子类的修改,显然会带来较大的不便。
    • 开闭原则的倾斜性(增加新的工厂和产品族容易,增加新的产品等级结构麻烦)。

UE4 实践

  • 做一个简单得怪物生成器,在不死族地带生成不死族怪物,在哥布林地带生成哥布林怪物;怪物分别有士兵和弓箭手两种

  • 创建抽象产品族类、抽象产品类——怪物、怪物士兵、怪物弓箭手

    1. // 抽象产品族类 —— 怪物
    2. UCLASS(Abstract)
    3. class DESIGNPATTERNS_API UMonster : public UObject
    4. {
    5. GENERATED_BODY()
    6. public:
    7. virtual void ShowInfo() { check(0 && "You must override this"); }
    8. };
    9. // 抽象产品类、具体产品族 —— 怪物士兵
    10. UCLASS(Blueprintable, BlueprintType)
    11. class DESIGNPATTERNS_API UMonsterSoldier : public UMonster
    12. {
    13. GENERATED_BODY()
    14. public:
    15. virtual void ShowInfo() override {
    16. UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" This is a Monster Soldier"));
    17. }
    18. };
    19. // 抽象产品类、具体产品族 —— 怪物弓箭手
    20. UCLASS(Blueprintable, BlueprintType)
    21. class DESIGNPATTERNS_API UMonsterArcher : public UMonster
    22. {
    23. GENERATED_BODY()
    24. public:
    25. virtual void ShowInfo() override {
    26. UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" This is a Monster Archer"));
    27. }
    28. };
  • 创建具体产品类——骷髅士兵、骷髅弓箭手、哥布林士兵、哥布林弓箭手

    1. // 具体产品类 —— 怪物士兵 —— 骷髅士兵
    2. UCLASS(Blueprintable, BlueprintType)
    3. class DESIGNPATTERNS_API UUndeadSkeletonSoldier : public UMonsterSoldier
    4. {
    5. GENERATED_BODY()
    6. public:
    7. virtual void ShowInfo() override {
    8. UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" This is a Undead Skeleton Soldier"));
    9. }
    10. };
    11. // 具体产品类 —— 怪物士兵 —— 哥布林士兵
    12. UCLASS(Blueprintable, BlueprintType)
    13. class DESIGNPATTERNS_API UGoblinSoldier : public UMonsterSoldier
    14. {
    15. GENERATED_BODY()
    16. public:
    17. virtual void ShowInfo() override {
    18. UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" This is a Goblin Soldier"));
    19. }
    20. };
    21. // 具体产品类 —— 怪物弓箭手 —— 骷髅弓箭手
    22. UCLASS(Blueprintable, BlueprintType)
    23. class DESIGNPATTERNS_API UUndeadSkeletonArcher : public UMonsterArcher
    24. {
    25. GENERATED_BODY()
    26. public:
    27. virtual void ShowInfo() override {
    28. UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" This is a Undead Skeleton Archer"));
    29. }
    30. };
    31. // 具体产品类 —— 怪物弓箭手 —— 哥布林弓箭手
    32. UCLASS(Blueprintable, BlueprintType)
    33. class DESIGNPATTERNS_API UGoblinArcher : public UMonsterArcher
    34. {
    35. GENERATED_BODY()
    36. public:
    37. virtual void ShowInfo() override {
    38. UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" This is a Goblin Archer"));
    39. }
    40. };
  • 创建抽象工厂类、具体工厂类——怪物生成器、不死族怪物生成器、哥布林怪物生成器

    1. // 抽象工厂类 —— 怪物生成器
    2. UCLASS(Abstract)
    3. class DESIGNPATTERNS_API UMonsterFactory : public UObject
    4. {
    5. GENERATED_BODY()
    6. public:
    7. // 生成士兵
    8. virtual UMonsterSoldier* CreateMonsterSoldier() {
    9. check(0 && "You must override this");
    10. return nullptr;
    11. }
    12. // 生成弓箭手
    13. virtual UMonsterArcher* CreateMonsterArcher(){
    14. check(0 && "You must override this");
    15. return nullptr;
    16. }
    17. };
    18. // 具体工厂类 —— 不死族怪物生成器
    19. UCLASS(Blueprintable, BlueprintType)
    20. class DESIGNPATTERNS_API UUndeadMonsterFactory : public UMonsterFactory
    21. {
    22. GENERATED_BODY()
    23. public:
    24. // 生成骷髅士兵
    25. virtual UMonsterSoldier* CreateMonsterSoldier() override {
    26. return NewObject<UUndeadSkeletonSoldier>(); // 实际使用 SpawnActor
    27. }
    28. // 生成骷髅弓箭手
    29. virtual UMonsterArcher* CreateMonsterArcher() override {
    30. return NewObject<UUndeadSkeletonArcher>();
    31. }
    32. };
    33. // 具体工厂类 —— 哥布林怪物生成器
    34. UCLASS(Blueprintable, BlueprintType)
    35. class DESIGNPATTERNS_API UGoblinMonsterFactory : public UMonsterFactory
    36. {
    37. GENERATED_BODY()
    38. public:
    39. // 生成哥布林士兵
    40. virtual UMonsterSoldier* CreateMonsterSoldier() override {
    41. return NewObject<UGoblinSoldier>(); // 实际使用 SpawnActor
    42. }
    43. // 生成哥布林弓箭手
    44. virtual UMonsterArcher* CreateMonsterArcher() override {
    45. return NewObject<UGoblinArcher>();
    46. }
    47. };
  • 测试调用

    1. // 调用测试用的Actor
    2. UCLASS()
    3. class DESIGNPATTERNS_API AMonsterGenerator : public AActor
    4. {
    5. GENERATED_BODY()
    6. public:
    7. void BeginPlay() override {
    8. // 不死族地带区域 生成怪物
    9. UUndeadMonsterFactory* UndeadMonsterFactory = NewObject<UUndeadMonsterFactory>();
    10. UndeadMonsterFactory->CreateMonsterSoldier()->ShowInfo();
    11. UndeadMonsterFactory->CreateMonsterArcher()->ShowInfo();
    12. // 哥布林地带生成 怪物
    13. UGoblinMonsterFactory* GoblinMonsterFactory = NewObject<UGoblinMonsterFactory>();
    14. GoblinMonsterFactory->CreateMonsterSoldier()->ShowInfo();
    15. GoblinMonsterFactory->CreateMonsterArcher()->ShowInfo();
    16. }
    17. };
  • 调式输出

    1. LogTemp: Warning: UUndeadSkeletonSoldier::ShowInfo This is a Undead Skeleton Soldier
    2. LogTemp: Warning: UUndeadSkeletonArcher::ShowInfo This is a Undead Skeleton Archer
    3. LogTemp: Warning: UGoblinSoldier::ShowInfo This is a Goblin Soldier
    4. LogTemp: Warning: UGoblinArcher::ShowInfo This is a Goblin Archer


参考

【UE4 设计模式】抽象工厂模式 Abstract Factory Pattern的更多相关文章

  1. 设计模式 - 抽象工厂模式(abstract factory pattern) 具体解释

    抽象工厂模式(abstract factory pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/2709 ...

  2. C#设计模式——抽象工厂模式(Abstract Factory Pattern)

    一.概述在软件开发中,常常会需要创建一系列相互依赖的对象,同时,由于需求的变化,往往存在较多系列对象的创建工作.如果采用常规的创建方法(new),会造成客户程序和对象创建工作的紧耦合.对此,抽象工厂模 ...

  3. 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern)

    原文:乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factor ...

  4. 【设计模式】抽象工厂模式 Abstract Factory Pattern

    简单工厂模式是一个工厂类根据工厂方法的参数创建不出不同的产品, 工厂方法模式是每一个产品都有一个一一对应的工厂负责创建该产品.那么今天要讲的抽象工厂模式是一个工厂能够产生关联的一系列产品.抽象工厂模式 ...

  5. 二十四种设计模式:抽象工厂模式(Abstract Factory Pattern)

    抽象工厂模式(Abstract Factory Pattern) 介绍提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 示例有Message和MessageModel,Messag ...

  6. 设计模式之抽象工厂模式(Abstract Factory Pattern)

    一.抽象工厂模式的由来 抽象工厂模式,最开始是为了解决操作系统按钮和窗体风格,而产生的一种设计模式.例如:在windows系统中,我们要用windows设定的按钮和窗体,当我们切换Linux系统时,要 ...

  7. Net设计模式实例之抽象工厂模式(Abstract Factory Pattern)

    一.抽象工厂模式简介(Bref Introduction) 抽象工厂模式(Abstract Factory Pattern),提供一个创建一系列相关或者相互依赖对象的接口,而无需制定他们的具体类.优点 ...

  8. Objective-C设计模式——抽象工厂模式Abstract Factory(对象创建)

    抽象工厂模式 理解了工厂方法模式,其实抽象工厂和工厂方法模式有很多的相似之处.抽象工厂同样是分离客户端对象的创建和逻辑代码的,但是抽象工厂往往是产生一组数据而不单单是产生一个产品. 抽象工厂提供一个创 ...

  9. 六个创建模式之抽象工厂模式(Abstract Factory Pattern)

    问题: 使用工厂方法模式的主要问题是工厂类过多,每个产品对应一个工厂,不利于维护.因此可以考虑使用一个工厂创建一个产品族. 定义: 提供创建一些列相关或相互依赖的对象实例的接口,这些类可以称为一个产品 ...

随机推荐

  1. 解决win10 cmd运行python弹出windows应用商店下python应用程序

    方法一: 1.我一开始下载完python后,忘记下载到哪个位置,在win10底下输入框搜索python,点击打开文件所在位置,所在位置是python快捷键的位置,直接复制进行环境配置 配置完环境变量后 ...

  2. layui的CRUD案列

    用layui来实现一个简单的二级权限和增删改查案列 利用layui提供的组件(table , layer , form,tree)来进行开发 写一个简单的登录界面   根据用户的ID来 获取用户所对应 ...

  3. Java - 注释、标识符、关键字

    背景 要开始磕 Java 了,虽然以前学过用过,但是差不多忘光光了... 现在直接搬狂神的视频素材,不再自己总结,要学的东西太多了... 注释 单行注释 // 多行注释 /* */ 文档注释 /** ...

  4. 《Go语言圣经》阅读笔记:第三章基础数据类型

    第三章 基础数据类型 Go语言将数据类型分为四类: 基础类型 数字 整数 浮点数 复数 字符串 布尔 复合类型 数据 结构体 引用类型 指针 切片 字典 函数 通道 接口类型 在此章节中先介绍基础类型 ...

  5. Java 语法学习2

    Java基础语法二 类型转换 public class demo03 { public static void main(String[] args) { int i=128; byte a=(byt ...

  6. vue项目实现文件下载进度条

    平时业务中下载文件方式常见的有俩种: 第一种,直接访问服务器的文件地址,自动下载文件: 第二种 ,服务器返回blob文件流,再对文件流进行处理和下载. 一般小文件适用于第一种下载方案,不占用过多服务器 ...

  7. Git 访问慢 解决办法

    1. 查询Git最快的IP 通过 https://www.ipaddress.com/ 这个网站来获取当前github最新的ip分别获取以下两个域名的IP地址: 可以在访问git网站使用F12查询哪个 ...

  8. Nginx系列(10)- Nginx配置文件详解

    nginx文件结构 ... #全局块 events { #events块 ... } http #http块 { ... #http全局块 server #server块 { ... #server全 ...

  9. php socket 发送http请求 GET POST

    http://docs.php-http.org/en/latest/httplug/users.html <?php /** * Created by PhpStorm. * User: Mc ...

  10. 鸿蒙内核源码分析(源码注释篇) | 鸿蒙必定成功,也必然成功 | 百篇博客分析OpenHarmony源码 | v13.02

    百篇博客系列篇.本篇为: v13.xx 鸿蒙内核源码分析(源码注释篇) | 鸿蒙必定成功,也必然成功 | 51.c.h .o 几点说明 kernel_liteos_a_note | 中文注解鸿蒙内核 ...