概述

描述

  • 建造者模式,又称生成器模式。是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

  • 建造者模式将客户端与包含多个组成部分的复杂对象的创建过程分离,客户端无需知道复杂对象的内部组成与装配方式,主需要知道所需的建造者即可。类似工厂方法,但是建造者模式返回一个完整的复杂产品,而抽象工厂模式则返回一系列相关的产品。以汽车为例,工厂方法可以看成不同汽车配件的生成,而建造者模式则可以看成时汽车的组装

套路

  • Builder:抽象建造者

    为创建一个产品对象的各个部件指定抽象接口,一般包含两个接口方法:一个用于创建复杂对象的各个部件;另一个用于返回生成好的复杂对象。它就可以是抽象类,也可以是接口。
  • ConcreteBuilder:具体建造者

    实现了Builder接口,即实现了各个部件的具体构造和装配方法,定义并明确其所创建的复杂对象。
  • Product:产品角色

    被构建的复杂对象,包含多个组成部件。
  • Director:指挥者

    负责安排复杂对象的建造次序,指挥者与抽象建造者之间存在关联关系,可以在其Construct()方法中调用建造者对象的部件构造和装配方法,完成复杂对象的建造。

使用场景

  • 需要生成的产品对象有复杂的内部结构,这些产品对象通常包含多个成员属性。
  • 需要生成的产品对象的属性相互依赖,需要指定其生成顺序。
  • 对象的创建过程独立于创建该对象的类。在建造者模式中引入了指挥者类,将创建过程封装在指挥者类中,而不在建造者类中。
  • 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品。
  • 示例
    • 不同门派角色生成,具有不同的服装、武器、发型
    • 不同地图生成,如道路、植被、天气、怪物。
    • 武器组装

优缺点

  • 优点

    • 客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
    • 用户使用不同的具体建造者即可得到不同的产品对象 。
    • 可以更加精细地控制产品的创建过程 。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制创建过程。
    • 增加新的具体建造者无须修改原有类库的代码,指挥者类针对抽象建造者类编程,系统扩展方便,符合“开闭原则”。
  • 缺点
    • 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似。如果产品之间的差异性很大,则不适合使用,因此其使用范围受到一定的限制。
    • 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。

UE4 实践

  • 做一个简单得门派生成器

  • 创建具体赋值产品 —— 门派角色角色

    // 复杂产品 —— 门派角色
    UCLASS(Blueprintable, BlueprintType)
    class DESIGNPATTERNS_API USectPlayer : public UObject
    {
    GENERATED_BODY()
    public:
    // 门派
    FString Sect = TEXT("None");
    // 性别
    FString Render = TEXT("None");
    // 服装
    FString Costume = TEXT("None");
    // 武器
    FString Weapon = TEXT("None"); // 展示信息
    void ShowInfo() {
    UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" %s %s %s %s"), *Sect, *Render, *Costume, *Weapon);
    }
    };
  • 创建抽象建造者 —— 角色构造器,具体建造者 —— 纯阳角色构造器、七秀角色构造器

    // 抽象建造者 —— 角色构造器
    UCLASS(Abstract)
    class DESIGNPATTERNS_API USectPlayerBuilder : public UObject
    {
    GENERATED_BODY()
    public:
    // 构造函数创建复杂角色实例
    USectPlayerBuilder() { SectPlayer = NewObject<USectPlayer>(); } // 各个构建部分
    virtual void BuilderSect(){}
    virtual void BuilderRender(){}
    virtual void BuilderCostume(){}
    virtual void BuilderWeapon(){} // 返回角色实例
    USectPlayer* GetPlayer() { return SectPlayer; }
    protected:
    USectPlayer* SectPlayer;
    }; // 具体建造者 —— 纯阳角色构造器
    UCLASS(Blueprintable, BlueprintType)
    class DESIGNPATTERNS_API UChunYangSectPlayerBuilder : public USectPlayerBuilder
    {
    GENERATED_BODY()
    public:
    virtual void BuilderSect() override { SectPlayer->Sect = TEXT("纯阳门派"); }
    virtual void BuilderRender() override { SectPlayer->Render = TEXT("男"); }
    virtual void BuilderCostume() override { SectPlayer->Costume = TEXT("纯阳服装"); }
    virtual void BuilderWeapon() override { SectPlayer->Weapon = TEXT("纯阳武器"); }
    }; // 具体建造者 —— 七秀角色构造器
    UCLASS(Blueprintable, BlueprintType)
    class DESIGNPATTERNS_API UQiXiuSectPlayerBuilder : public USectPlayerBuilder
    {
    GENERATED_BODY()
    public:
    virtual void BuilderSect() override { SectPlayer->Sect = TEXT("七秀门派"); }
    virtual void BuilderRender() override { SectPlayer->Render = TEXT("女"); }
    virtual void BuilderCostume() override { SectPlayer->Costume = TEXT("七秀服装"); }
    virtual void BuilderWeapon() override { SectPlayer->Weapon = TEXT("七秀武器"); }
    };
  • 创建指挥者(Director) —— 角色创建指挥者

    // 指挥者(Director) —— 角色创建指挥者
    UCLASS(Blueprintable, BlueprintType)
    class DESIGNPATTERNS_API UPlayerCreateDirectory : public USectPlayerBuilder
    {
    GENERATED_BODY()
    public:
    USectPlayer* Construct(USectPlayerBuilder* SectPlayerBuilder) {
    // 逐步构建复杂角色
    SectPlayerBuilder->BuilderSect();
    SectPlayerBuilder->BuilderRender();
    SectPlayerBuilder->BuilderCostume();
    SectPlayerBuilder->BuilderWeapon(); return SectPlayerBuilder->GetPlayer();
    }
    };
  • 测试调用

    // 调用测试用的Actor
    UCLASS()
    class DESIGNPATTERNS_API APlayerBuilder : public AActor
    {
    GENERATED_BODY()
    public: void BeginPlay() override { // 创建指挥者
    UPlayerCreateDirectory* PlayerCreateDirectory = NewObject<UPlayerCreateDirectory>(); // 指定纯阳角色构造器生成角色
    USectPlayer* ChunYangPlayer = PlayerCreateDirectory->Construct(NewObject<UChunYangSectPlayerBuilder>());
    ChunYangPlayer->ShowInfo(); // 指定七秀角色构造器生成角色
    USectPlayer* QiXiuPlayer = PlayerCreateDirectory->Construct(NewObject<UQiXiuSectPlayerBuilder>());
    QiXiuPlayer->ShowInfo();
    }
    };
  • 调式输出

    LogTemp: Warning: APlayerBuilder::BeginPlay 纯阳门派 男 纯阳服装 纯阳武器
    LogTemp: Warning: APlayerBuilder::BeginPlay 七秀门派 女 七秀服装 七秀武器


参考

【UE4 设计模式】建造者模式 Builder Pattern的更多相关文章

  1. 设计模式 - 建造者模式 Builder Pattern

    简介 场景 在创建复杂对象时,用户无须关心该对象所包含的属性以及它们的组装方式,只需要指定复杂对象的类型和内容就可以构建它们. 模式定义 建造者模式:将一个复杂对象的构建与表示分离,使得同样的构建过程 ...

  2. 23种设计模式--建造者模式-Builder Pattern

    一.建造模式的介绍       建造者模式就是将零件组装成一个整体,用官方一点的话来讲就是将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示.生活中比如说组装电脑,汽车等等这些都是建 ...

  3. 【原】iOS设计模式之:建造者模式Builder Pattern,用于改进初始化参数

    本文主要讨论一下iOS中的Builder Pattern.与网上很多版本不同,本文不去长篇大论地解释建造者模式的概念,那些东西太虚了.设计模式这种东西是为了解决实际问题的,不能为了设计模式而设计模式, ...

  4. 乐在其中设计模式(C#) - 建造者模式(Builder Pattern)

    原文:乐在其中设计模式(C#) - 建造者模式(Builder Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 建造者模式(Builder Pattern) 作者:webabc ...

  5. 【设计模式】建造者模式 Builder Pattern

    前面学习了简单工厂模式,工厂方法模式以及抽象工厂模式,这些都是创建类的对象所使用的一些常用的方法和套路, 那么如果我们创建一个很复杂的对象可上面的三种方法都不太适合,那么“专业的事交给专业人去做”,2 ...

  6. iOS设计模式之:建造者模式Builder Pattern,用于改进初始化参数

    转自:http://www.cnblogs.com/wengzilin/p/4365855.html 本文主要讨论一下iOS中的Builder Pattern.与网上很多版本不同,本文不去长篇大论地解 ...

  7. 设计模式系列之建造者模式(Builder Pattern)——复杂对象的组装与创建

    说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...

  8. 二十四种设计模式:建造者模式(Builder Pattern)

    建造者模式(Builder Pattern) 介绍将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 示例用同样的构建过程创建Sql和Xml的Insert()方法和Get()方 ...

  9. 建造者模式(Builder Pattern)

    建造者模式(Builder Pattern) 它可以将多个简单的对象一步一步构建成一个复杂的对象. 意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示. 主要解决:主要解决在软 ...

  10. 设计模式—建造者模式(Builder)

    title: 设计模式-建造者模式 建造者模式(Builder)是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节.建造者模式属于对 ...

随机推荐

  1. 初识Ansible 01

    自动化运维工具有很多,从实现的功能.维护的成本.使用的系统来选择,几种常用运维工具比较: Puppet基于 Ruby 开发,采用 C/S 架构,扩展性强,基于 SSL,远程命令执行相对较弱 SaltS ...

  2. scikit-learn 1.0 版本新特性及变动前瞻性预览

    1 简介 就在几天前,著名的机器学习框架scikit-learn在pypi上释放了其1.0rc1版本,这里给大家科普一下,版本号中的rc是Release Candidate的简称,代表当前的版本是一个 ...

  3. vue-过滤器(filter)的使用详解

    前言 Vue 允许我们在项目中定义过滤器对我们页面的文本展示进行格式的控制,本文就来总结一下过滤器在项目中的常见使用方法. 正文 1.局部过滤器的注册 (1)无参局部过滤器 <div id=&q ...

  4. 珠峰2016,第9期 vue.js 笔记部份

    在珠峰参加培训好年了,笔记原是记在本子上,现在也经不需要看了,搬家不想带上书和本了,所以把笔记整理下,存在博客中,也顺便复习一下 安装vue.js 因为方便打包和环境依赖,所以建意npm  init  ...

  5. C# .NET Core 3.1 中 AssemblyLoadContext 的基本使用

    C# .NET Core 3.1 中 AssemblyLoadContext 的基本使用 前言 之前使用 AppDomain 写过一个动态加载和释放程序的案例,基本实现了自己"兔死狗烹&qu ...

  6. scrum项目冲刺_day01总结

    摘要:今日完成任务. 1.app基本框架页面正在进行 2.图像识别正在进行 总任务: 一.appUI页面 二.首页功能: 1.图像识别功能 2.语音识别功能 3.垃圾搜索功能 4.相关新闻爬取 三.我 ...

  7. Java从入门到精通(第5版)上半部分

    1.1java简介 先起了oak 橡树 这个名字,因为商标原因改为爪洼岛谐音的Java 一次编写,到处运行 java如何运行 java程序既是编译型又是解释型 Java版本 Java SE 标准版(开 ...

  8. PHP中的PDO操作学习(二)预处理语句及事务

    今天这篇文章,我们来简单的学习一下 PDO 中的预处理语句以及事务的使用,它们都是在 PDO 对象下的操作,而且并不复杂,简单的应用都能很容易地实现.只不过大部分情况下,大家都在使用框架,手写的机会非 ...

  9. JMeter脚本开发

    什么是jmeter脚本 用户操作系统的动作流程 用户操作系统的请求 类似演戏的剧本 怎么快速开发漂亮的jmeter脚本 准确 快速 漂亮,脚本逻辑清晰,维护性高 脚本开发方案 代理 http代理服务器 ...

  10. three.js 模型常用操作

    场景: THREE.Scene();   场景辅助坐标模型: THREE.AxesHelper(20);   相机: THREE.PerspectiveCamera()// 透视相机 THREE.Or ...