• UE4 C++设计模式:适配器模式(Adapter Pattern)


    目录

    描述

    套路

    使用场景

    优缺点

    UE4实践

    创建目标抽象类(接口形式)

    创建目标适配者类:Uffmpeg、UVLC

    创建适配器类(继承自目标抽象类):UffmpegAdapter、UVLCAdapter


    描述

    将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,又称包装器(Wrapper)

    套路

    • Target(目标抽象类)
      • 定义客户所需要的接口,可以是一个抽象类或接口,也可以是一个具体的类
    • Adapter(适配器类)
      • 适配器可以调用另一个接口,作为一个转换器,对Adapter和Target进行适配;
      • 适配器类是Adapter Pattern的核心,他通过继承Target并关联一个Adaptee对象使二者产生联系
    • Adaptee(适配者类)
      • 适配者即被适配的角色,它定义了一个已经存在的接口,这个接口需要适配,一般是一个具体类,包含了客户希望使用的业务方法,在某些情况下可能没有适配者类的源代码

    使用场景

    • 系统需要使用现有的类,而这些类的接口不符合系统的要求
    • 想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作
    • 示例:
      • 为了处理项目代码更新后与原来接口不兼容,可以创建适配器来保证“旧调新”、“新调旧”的功能需求
      • 已定下接口后,要求调用第三方SDK等(类似于电源适配器,要求输出12V,但是输入220V)

    优缺点

    • 优点
      • 将目标类和适配器类解耦,通过引入一个适配器类来重用现有的适配者类,而无需修改原有代码
      • 增加类的透明性和复用性,将具体的实现封装在适配者类中,对于客户端来说是透明的,而且提高了适配者的复用性
      • 灵活性和扩展性好,通过使用配置文件,可以很方便的更换适配器,也可以在不修改原有代码的基础上增加行的适配器类,完全符合开闭原则
    • 缺点
      • 过多的使用适配器,会让系统非常零乱,不易整体进行把握

    UE4实践

    自定义一个媒体模仿器,接口已经写好,为了使第三方SDK适应自己的接口,此时可以使用适配器

    创建目标抽象类(接口形式)

    1. UINTERFACE(MinimalAPI)
    2. class UMediaInterface : public UInterface
    3. {
    4. GENERATED_BODY()
    5. };
    6. class DESIGNPATTERNS_API IMediaInterface
    7. {
    8. GENERATED_BODY()
    9. public:
    10. virtual void PlayVideo(const FString& Filepath) = 0;
    11. };

    创建目标适配者类:Uffmpeg、UVLC

    1. UCLASS() // 适配者类 —— ffmpeg
    2. class DESIGNPATTERNS_API Uffmpeg : public UObject
    3. {
    4. GENERATED_BODY()
    5. public:
    6. virtual void OpenFile(const FString& Filepath) {
    7. UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" use ffmpeg sdk to play media"));
    8. }
    9. };
    10. UCLASS() // 适配者类 —— VLC
    11. class DESIGNPATTERNS_API UVLC : public UObject
    12. {
    13. GENERATED_BODY()
    14. public:
    15. virtual void OpenFile(const FString& Filepath) {
    16. UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" use VLC sdk to play media"));
    17. }
    18. };

    创建适配器类(继承自目标抽象类):UffmpegAdapter、UVLCAdapter

    重载接口函数,调用其他接口来适应新的接口

    1. UCLASS() // 适配器类 —— UffmpegAdapter
    2. class DESIGNPATTERNS_API UffmpegAdapter : public UObject, public IMediaInterface
    3. {
    4. GENERATED_BODY()
    5. public:
    6. UPROPERTY()
    7. Uffmpeg* m_pffmpegSDK;
    8. UffmpegAdapter() {
    9. m_pffmpegSDK=NewObject();
    10. }
    11. ~UffmpegAdapter() {}
    12. virtual void PlayVideo(const FString& Filepath) override {
    13. m_pffmpegSDK->OpenFile(Filepath);
    14. }
    15. };
    1. UCLASS() // 适配器类 —— UVLCAdapter
    2. class DESIGNPATTERNS_API UVLCAdapter: public UObject, public IMediaInterface
    3. {
    4. GENERATED_BODY()
    5. public:
    6. UPROPERTY()
    7. UVLC* m_pVLCSDK;
    8. UVLCAdapter() {
    9. m_pVLCSDK = NewObject();
    10. }
    11. ~UVLCAdapter() {}
    12. virtual void PlayVideo(const FString& Filepath) override {
    13. m_pVLCSDK->OpenFile(Filepath);
    14. }
    15. };

    测试

    1. UCLASS()
    2. class DESIGNPATTERNS_API AAdapterTestActor : public AActor
    3. {
    4. GENERATED_BODY()
    5. public:
    6. AAdapterTestActor();
    7. protected:
    8. // Called when the game starts or when spawned
    9. virtual void BeginPlay() override {
    10. // 使用 ffmpegAdapter 适配器
    11. IMediaInterface* MediaPlayer = Cast(NewObject());
    12. MediaPlayer->PlayVideo(TEXT("C:/浪客剑心.最终章.人诛篇.mp4"));
    13. // 使用 VLCAdapter 适配器
    14. MediaPlayer = Cast(NewObject());
    15. MediaPlayer->PlayVideo(TEXT("C:/浪客剑心.最终章.人诛篇.mp4"));
    16. }
    17. };

    LogTemp: Warning: Uffmpeg::OpenFile use ffmpeg sdk to play media
    LogTemp: Warning: UVLC::OpenFile use VLC sdk to play media
     

    1. 适配器模式 — Graphic Design Patterns (design-patterns.readthedocs.io)

     

  • 相关阅读:
    uni-app scroll-view设置scrollTop为0返回顶部不生效
    实战:Linux下静默安装DM达梦数据库
    通用分页(分页代码的封装)
    【MOL PLANT PATHOL】苹果MdMRLK2 通过抑制防御反应和过敏反应负向调节对V. mali的抗性
    vim打开当前目录
    beego开发博客系统学习(二)
    服务器集群配置LDAP统一认证高可用集群(配置tsl安全链接)-centos9stream-openldap2.6.2
    【DETR源码解析】三、Transformer模块
    数据结构与算法 树 课后习题 选择题部分
    nodejs 模块
  • 原文地址:https://blog.csdn.net/Jason6620/article/details/126540812