• UE4 C++设计模式:装饰模式


    目录

    描述

    套路

    使用场景

    优缺点

    UE4实践

    创建抽象组件类

    创建具体组件类

    创建装饰具体类(省略抽象类)


    描述

    动态的给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类实现更为灵活,是一种对象结构型模式。

    套路

    • 抽象组件(Component)
      • 具体组件和抽象装饰类的基类,声明具体组件中实现业务的方法
    • 具体组件(ConcreteComponent)
      • 抽象组件的子类,用于定义具体的组件对象,实现了抽象组件中声明的方法,装饰器可以给他增加额外的职责
    • 抽象装饰类(Decorator)
      • 它也是抽象组件类的子类,用于给具体组件增加职责,但是具体职责在其子类中实现
    • 具体装饰类(ConcreteDecorator)
      • 抽象装饰类的子类,负责向组件添加新的职责

    使用场景

    • 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责
    • 需要动态的给一个对象增加职责,这些功能也可以动态的被撤销
    • 当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时;
      • 系统中存在大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸式增长
      • 类定义不能继承(如final)
    • 实例
      • 一些api的参数请求追加签名验证
      • 数据的增删改查、会包含登录验证的功能,然后再进行对应的操作
      • 原来单一的日志记录,追加上传、归档
      • 已经设计好的游戏物品,因为临时需求想要扩展额外的功能

    优缺点

    • 优点
      • 对于扩展一个对象的功能,装饰模式比继承更加灵活
      • 可以对一个对象进行多次装饰,从而创造出很多不同行为的组合
      • 具体组件与具体装饰可以独立变化,用户可以根据需要增加新的具体组件和具体装饰类,在使用时再对其进行组合,原油代码无需改变,符合开闭原则
    • 缺点
      • 使用装饰模式进行系统设计将产生很多小对象,这些对象的区别在于他们之间相互连接的方式有所不同,而不是他们的类或者属性值有所不同,同时还将产生很多具体装饰类。这些装饰类和小对线将增加系统的复杂度,加大学习和理解的难度
      • 这种比继承更加灵活的特性,也同时意味着装饰模式比继承更加容易出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为麻烦

    UE4实践

    以前的账户登录:账号+密码

    现在的账户登录:账号+密码+人脸识别

    可以把人脸识别用装饰器实现

    创建抽象组件类

    1. UCLASS(Abstract) // 抽象构件类 —— 账户登录
    2. class DESIGNPATTERNS_API ULogin : public UObject
    3. {
    4. GENERATED_BODY()
    5. protected:
    6. public:
    7. virtual bool LoginVerify(const FString& pName, const FString& pPassword) {
    8. return true;
    9. }
    10. };

    创建具体组件类

    1. UCLASS() // 具体构件类 —— 账户登录 联网版本
    2. class DESIGNPATTERNS_API UWebLogin : public ULogin
    3. {
    4. GENERATED_BODY()
    5. protected:
    6. public:
    7. virtual bool LoginVerify(const FString& pName, const FString& pPassword) override {
    8. bool result;
    9. UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" LinkWeb:Account ID Verify"));
    10. result = true;
    11. return result;
    12. }
    13. };

    创建装饰具体类(省略抽象类)

    1. UCLASS() // 装饰器具体类 —— 扩展人脸识别步骤
    2. class DESIGNPATTERNS_API UWebLoginWithFaceID : public ULogin
    3. {
    4. GENERATED_BODY()
    5. protected:
    6. // 被装饰的对象
    7. UPROPERTY();
    8. ULogin* m_pLoginObj;
    9. public:
    10. // 初始化被装饰的对象
    11. void Init(ULogin* pLoginObj) {
    12. m_pLoginObj = pLoginObj;
    13. }
    14. // 装饰的新功能 —— 人脸识别
    15. bool FaceIDVerify(const FString& pName) {
    16. UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" %s Face ID Verify"), *pName);
    17. return true;
    18. }
    19. virtual bool LoginVerify(const FString& pName, const FString& pPassword) override {
    20. bool result;
    21. result = m_pLoginObj->LoginVerify(pName, pPassword);
    22. // 追加人脸识别步骤
    23. result = result && FaceIDVerify(pName);
    24. return result;
    25. }
    26. };

    测试

    1. UCLASS()
    2. class DESIGNPATTERNS_API ADecoratorTestActor : public AActor
    3. {
    4. GENERATED_BODY()
    5. public:
    6. ADecoratorTestActor();
    7. virtual void Tick(float DeltaTime) override;
    8. protected:
    9. // Called when the game starts or when spawned
    10. virtual void BeginPlay() override {
    11. // 被装饰对象及登录步骤
    12. ULogin* WebLogin = NewObject();
    13. WebLogin->LoginVerify("admin", "123456");
    14. // 装饰器对象及初始化
    15. UWebLoginWithFaceID* WebLoginWithFaceID = NewObject();
    16. WebLoginWithFaceID->Init(WebLogin);
    17. // 装饰后的登录步骤
    18. WebLoginWithFaceID->LoginVerify("admin", "123456");
    19. }
    20. };
    1. # 旧登录方式
    2. LogTemp: Warning: UWebLogin::LoginVerify LinkWeb:Account ID Verify
    3. # 新登录方式
    4. LogTemp: Warning: UWebLogin::LoginVerify LinkWeb:Account ID Verify
    5. LogTemp: Warning: UWebLoginWithFaceID::FaceIDVerify admin Face ID Verify

     

  • 相关阅读:
    【C++进阶之路】第八篇:智能指针
    【老生谈算法】matlab实现三相短路电流计算源码——短路电流
    CUDA 解释 - 深度学习为何使用 GPU
    MetaGPT部分源码解读
    2020年Github上最牛的Java进阶教程及Java实战项目都在这里了!
    263.3的幂
    如何通过远程桌面连接另一台电脑
    将Pytorch搭建的ViT模型转为onnx模型
    Spring Security整合企业微信的扫码登录,企微的API震惊到我了
    JVM和字节码的关系
  • 原文地址:https://blog.csdn.net/Jason6620/article/details/126540275