【UE4 设计模式】装饰器模式 Decorator Pattern
概述
描述
动态地给一个对象增加一些额外的职责(Responsibility),就增加对象功能来说,装饰模式比生成子类实现更为灵活。是一种对象结构型模式。

套路
- 抽象构件(Component)
具体构件和抽象装饰类的基类,声明了在具体构建中实现的业务方法。 - 具体构件(ConcreteComponent)
抽象构件的子类,用于定义具体的构件对象,实现了在抽象构件中声明的方法,装饰器可以给它增加额外的职责(方法)。 - 抽象装饰类(Decorator)
它也是抽象构件类的子类,用于给具体构件增加职责,但是具体职责在其子类中实现。 - 具体装饰类(ConcreteDecorator)
抽象装饰类的子类,负责向构件添加新的职责。
使用场景
- 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
- 需要动态地给一个对象增加功能,这些功能也可以动态地被撤销。
- 当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时。不能采用继承的情况主要有两类:第一类是系统中存在大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长;第二类是因为类定义不能继承(如final类).
- 示例
- 一些api的参数请求追加签名验证
- 数据的增删修改,会包含登录验证的功能、然后再进行对应的操作;
- 原来单一的日志记录,追加上传、归档等功能
- 已经设计好的游戏物品,因为临时需求想要扩展额外的功能
优缺点
- 优点
- 对于扩展一个对象的功能,装饰模式比继承更加灵活
- 可以对一个对象进行多次装饰,从而创造出很多不同行为的组合
- 具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,在使用时再对其进行组合,原有代码无须改变,符合“开闭原则”
- 缺点
- 使用装饰模式进行系统设计时将产生很多小对象,这些对象的区别在于它们之间相互连接的方式有所不同,而不是它们的类或者属性值有所不同,同时还将产生很多具体装饰类。这些装饰类和小对象的产生将增加系统的复杂度,加大学习与理解的难度。
- 这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加易于出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为烦琐。
UE4 实践
以前进行账户登录都是直接账户密码就可以,后来为了更安全,更好的采集用户的数据,于是都喜欢加上人脸识别了。这时,可以把人脸识别这一步用装饰器来实现
创建构件抽象类、具体类
UCLASS(Abstract) // 抽象构件类 —— 账户登录
class DESIGNPATTERNS_API ULogin : public UObject
{
GENERATED_BODY() protected: public:
virtual bool LoginVerify(const FString& pName, const FString& pPassword) {
return true;
}
}; UCLASS() // 具体构件类 —— 账户登录 联网版本
class DESIGNPATTERNS_API UWebLogin : public ULogin
{
GENERATED_BODY() protected: public:
virtual bool LoginVerify(const FString& pName, const FString& pPassword) override {
bool result;
UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" LinkWeb:Account ID Verify"));
result = true;
return result;
}
};
创建装饰具体类(省略抽象类)
UCLASS() // 装饰器具体类 —— 扩展人脸识别步骤
class DESIGNPATTERNS_API UWebLoginWithFaceID : public ULogin
{
GENERATED_BODY() protected:
// 被装饰的对象
UPROPERTY();
ULogin* m_pLoginObj;
public:
// 初始化被装饰的对象
void Init(ULogin* pLoginObj) {
m_pLoginObj = pLoginObj;
} // 装饰的新功能 —— 人脸识别
bool FaceIDVerify(const FString& pName) {
UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" %s Face ID Verify"), *pName);
return true;
} virtual bool LoginVerify(const FString& pName, const FString& pPassword) override {
bool result;
result = m_pLoginObj->LoginVerify(pName, pPassword);
// 追加人脸识别步骤
result = result && FaceIDVerify(pName);
return result;
}
};
调用测试
UCLASS()
class DESIGNPATTERNS_API ADecoratorTestActor : public AActor
{
GENERATED_BODY() public:
ADecoratorTestActor();
virtual void Tick(float DeltaTime) override; protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override {
// 被装饰对象及登录步骤
ULogin* WebLogin = NewObject<UWebLogin>();
WebLogin->LoginVerify("admin", "123456"); // 装饰器对象及初始化
UWebLoginWithFaceID* WebLoginWithFaceID = NewObject<UWebLoginWithFaceID>();
WebLoginWithFaceID->Init(WebLogin); // 装饰后的登录步骤
WebLoginWithFaceID->LoginVerify("admin", "123456");
}
};
调式输出
# 旧登录方式
LogTemp: Warning: UWebLogin::LoginVerify LinkWeb:Account ID Verify # 新登录方式
LogTemp: Warning: UWebLogin::LoginVerify LinkWeb:Account ID Verify
LogTemp: Warning: UWebLoginWithFaceID::FaceIDVerify admin Face ID Verify
参考
【UE4 设计模式】装饰器模式 Decorator Pattern的更多相关文章
- 浅谈设计模式--装饰者模式(Decorator Pattern)
挖了设计模式这个坑,得继续填上.继续设计模式之路.这次讨论的模式,是 装饰者模式(Decorator Pattern) 装饰者模式,有时也叫包装者(Wrapper),主要用于静态或动态地为一个特定的对 ...
- 设计模式 - 装饰者模式(Decorator Pattern) Java的IO类 用法
装饰者模式(Decorator Pattern) Java的IO类 用法 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26716 ...
- 设计模式 - 装饰者模式(Decorator Pattern) 具体解释
装饰者模式(Decorator Pattern) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26707033 装饰者 ...
- 23种设计模式之装饰器模式(Decorator Pattern)
装饰器模式(Decorator Pattern) 允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包 ...
- python 设计模式之装饰器模式 Decorator Pattern
#写在前面 已经有一个礼拜多没写博客了,因为沉醉在了<妙味>这部小说里,里面讲的是一个厨师苏秒的故事.现实中大部分人不会有她的天分.我喜欢她的性格:总是想着去解决问题,好像从来没有怨天尤人 ...
- c#设计模式之装饰器模式(Decorator Pattern)
引子 在面向对象语言中,我们常常会听到这样一句话:组合优于继承.那么该如何去理解这句话呢? 下面我将以游戏装备为模型用简单的代码去展示它 先创建一个装备的抽象类,然后创建刀枪2个具体的业务子类 pub ...
- 设计模式(三)——装饰器模式(Decorator Pattern)
发现太过于刻意按照计划来写博客,有点不实际,刚好最近在一个网课上复习AOP的知识,讲到了装饰器模式和代理模式,顺便复习总结一下. 首先了解一下装饰器模式,从名字里面可以看出来,装饰器模式就类似于房子装 ...
- 说说设计模式~装饰器模式(Decorator)~多功能消息组件的实现
返回目录 为何要设计多功能消息组件 之前写过一篇装饰器模式的文章,感觉不够深入,这次的例子是实现项目中遇到的,所以把它拿出来,再写写,之前也写过消息组件的文章,主要采用了策略模式实现的,即每个项目可以 ...
- 说说设计模式~装饰器模式(Decorator)
返回目录 装饰器模式,也叫又叫装饰者模式,顾名思义,将一个对象进行包裹,包装,让它变成一个比较满意的对象,这种模式在我们平时项目开发中,经常会用到,事实上,它是处理问题的一种技巧,也很好的扩展了程序, ...
- 用最简单的例子理解装饰器模式(Decorator Pattern)
假设有一个公司要做产品套餐,即把不同的产品组合在一起,不同的组合对应不同的价格.最终呈现出来的效果是:把产品组合的所有元素呈现出来,并显示该组合的价格. 每个产品都有名称和价格,首先设计一个关于产品的 ...
随机推荐
- 什么是云效持续集成?如何关联Jenkins进行持续集成?
什么是云效持续集成?如何关联Jenkins进行持续集成?云效流水线 Flow是一款企业级.自动化的研发交付流水线, 提供灵活易用的持续集成.持续验证. 持续发布功能,帮助企业高质量.高效率的交付业务. ...
- Identity用户管理入门二(显示用户列表)
在Controllers中新建AccountController,并在构造方法(函数)中注入SignInManager,UserManager UserManager 用户管理(注册,查找,修改, ...
- 一文带你了解.Net读写锁
本文主要讲解.Net基于ReaderWriterLockSlim讲解读写锁 基础概念 读写锁是一个具有特殊用途的线程锁,适用于频繁读取且读取需要一定时间的场景,共享资源的读取操作通常是可以同时执行的, ...
- 洛谷P1309——迷宫(傻瓜DFS)
题目背景 迷宫 [问题描述] 给定一个N*M方格的迷宫,迷宫里有T处障碍,障碍处不可通过.给定起点坐标和 终点坐标,问: 每个方格最多经过1次,有多少种从起点坐标到终点坐标的方案.在迷宫 中移动有上下 ...
- 1.26学习总结——css盒子模型
CSS 盒子模型(Box Model) 所有HTML元素可以看作盒子,在CSS中,"box model"这一术语是用来设计和布局时使用. CSS盒模型本质上是一个盒子,封装周围的H ...
- Java面向对象系列(5)- 构造器详解
构造器: 和类名相同 没有返回值 作用: new本质在调用构造器 初始化对象的值 注意点: 定义了有参构造之后,如果想要使用有参构造,必须显示的定义一个无参构造 IDEA快捷键: Alt + Inse ...
- Java基础系列(38)- 数组的使用
数组的使用 For-Each循环 数组作方法入参 数组作返回值 For-Each循环 普通型 package array; import sun.security.util.Length; publi ...
- java eclipse 使用随笔
1,无法import java.awt. 等各种文件,解决办法:(在module-info.java文件中加入requires java,desktop这句话)
- JMeter主要元件
配置元件 http cookie管理器 http信息头管理器 http请求默认值 统一管理 快速切换测试环境 http cache管理器 静态资源 监听器元件 查看结果树 分析查看某个请求的详情 请求 ...
- struts2 使用ajax进行图片上传
第一步:引入一个插件 jquery.form.js /*! * jQuery Form Plugin * version: 3.36.0-2013.06.16 * @requires jQuer ...