Adapter(适配器)模式总结

  • 前言
  • 一、适配器模式总结
    • 1、模式意图
    • 2、参与者
    • 3、类适配器结构及效果
    • 4、对象适配器结构及效果
  • 二、对象适配器C语言用例
    • 1、用例背景描述
    • 2、用例结构图
    • 3、用例Target类
    • 4、用例Adaptee接口
    • 5、用例Adapter类定义
    • 6、用例Adapter类实现
    • 7、用例Client
  • 总结

前言

本周五参加了Adapter(适配器)模式研讨会,本文的目的是对这个模式的总结和分享,希望对需要学习这个设计模式的同学有所帮助。本文一共分为两个部分,第一个部分是适配器模式的基础知识总结;第二个部分是使用适配器模式的一个例子分享。


一、适配器模式总结

适配器模式有两种子模式:类适配器和对象适配器,这两种子模式的意图是一致的,参与者是一致的,只是结构不同,效果有差异。类适配器采用继承的方式适配Adaptee,而对象适配器采用的是聚合方式适配Adaptee。

1、模式意图

将一个类的接口转换成客户希望的另一个接口。Adapter模式使得接口不兼容的类可以一起工作。

2、参与者

Target
-- 定义Client使用的接口。
Client
-- 与Target接口对象协同。
Adaptee
-- 需要适配的,已经存在的接口
Adapter
-- 对Adaptee和Target接口进行适配。

3、类适配器结构及效果

类适配器结构图:

效果:

1、使用一个具体的Adapter类对Adaptee和Target进行匹配,这使得不能匹配具体Adapter的子类。
2、可以使Adapter可以重定义Adaptee的部分行为。
3、仅仅引入了一个对象,并不需要额外的指向Adaptee的指针。

4、对象适配器结构及效果

对象适配器的结构图:

效果:
1、允许一个Adapter与多个Adaptee(及其子类对象)协同工作。
2、使得重定义Adaptee的行为比较困难。


二、对象适配器C语言用例

1、用例背景描述

在can总线中,我们总是希望把总线上接收到的帧保存到文件当中,方便对接收到的数据进行解析和分析。保存的文件格式是CSV、ASC等可视化的文件格式,由于客户的需求不断变化,记录数据的文件格式除了CSV、ASC外,还需要支持BLF格式文件。blf格式是一种加密文件,已经有现成的库,提供了操作blf文件接口。我们的文件记录模块需要支持blf文件,重新实现blf的逻辑是不现实的,因为我们不知道文件的结构,但是利用已有的库是可以实现blf存储的,这就需要我们对blf库进行封装,增加一个适配器,适配blf接口和统一文件存储接口。通过适配,我们存储blf可以和CSV等格式保持一致。

2、用例结构图

3、用例Target类

这里我们仅展示需要用到的公共接口,其他接口,例如构造和析构等接口省略。


struct file_operation_t;
typedef ret_t (*open_file_t)(file_operation_t *file_operation, const char *file_name, bool_t is_save);typedef ret_t (*close_file_t)(file_operation_t *file_operation);typedef char*  (*read_data_t)(file_operation_t *file_operation);typedef ret_t  (*write_data_t)(file_operation_t *file_operation, const char *data);typedef struct _file_operation_vtable_t {open_file_t open;close_file_t close;read_data_t read;write_data_t write;
} file_operation_vtable_t;typedef struct _file_operation_t {char *file_name;void *file_handle;int offset;file_operation_vtable_t *vt;
} file_operation_t;file_operation_t *file_operation_create();// 实现static const file_operation_vtable_t s_file_operation_vtable = {.open = NULL,
.close = NULL,
.read = NULL;
.write = NULL;
};file_operation_t *file_operation_create() {file_operation_t *obj = (file_operation_t *)malloc(sizeof(file_operation_t));obj->vt = &s_file_operation_vtable;return obj;
}

4、用例Adaptee接口

blf接口也提供了能完成Target功能的接口。

//创建文件,对应open_file
void *BlCreateFile(const char *file_name, int open_type);
//关闭文件,对应close_file
bool_t BLCloseHandle(void *handle);
//读文件,对应read_data
char* BlReadObject(void *handle);
//写文件,对应write_data
int BlWriteObject(void *handle, const char *data);

5、用例Adapter类定义

这个例子中,我们只能采用对象适配器模式来实现适配器,因为我们没办法继承一个库来实现类适配器,只能通过对象的方式来适配已有的库功能。我们需要公有继承Target,然后在实现代码中应用Adaptee的接口来实现blf文件操作。

typedef struct _blf_file_operation_t {file_operation_t parent;
} blf_file_operation_t;file_operation_t *blf_file_operation_create();

6、用例Adapter类实现

通过blf库提供的接口实现blf文件的打开、关闭和读写。


static ret_t open_file(file_operation_t *file_operation, const char *file_name, bool_t is_save) {void *handle;return_value_if_fail(file_operation != NULL && file_name != NULL, RET_BAD_PARAMS);if (is_save) {handle = BlCreateFile(file_name, GENERIC_WRITE);} else {handle = BlCreateFile(file_name, GENERIC_READ);}file_operation->file_handle = handle;return RET_OK;
}static ret_t close_file(file_operation_t *file_operation) {return_value_if_fail(file_operation != NULL, RET_BAD_PARAMS);BLCloseHandle(file_operation->file_handle);return RET_OK;
}static char* read_data(file_operation_t *file_operation) {return_value_if_fail(file_operation != NULL, NULL);return BlReadObject(file_operation->file_handle);
}static ret_t write_data(file_operation_t *file_operation, const char *data) {return_value_if_fail(file_operation != NULL && data != NULL, RET_BAD_PARAMS);return BlWriteObject(file_operation->file_handle, data);
}static const file_operation_vtable_t s_blf_file_operation_vtable = {.open = open_file,
.close = close_file,
.read = read_data;
.write = write_data;
};file_operation_t *blf_file_operation_create() {file_operation_t *obj = (file_operation_t *)malloc(sizeof(blf_file_operation_t));obj->vt = &s_blf_file_operation_vtable;return obj;
}

7、用例Client

客户端代码接口只用基类指针,这样,客户就不必关心具体用的是哪一种文件格式了,接口都是统一的。

file_operation_t *get_file_operation_obj();ret_t do_open(file_operation_t *file_operation, const char* file_name);
ret_t do_close(file_operation_t *file_operation);
...//实现
ret_t do_open(file_operation_t *file_operation, const char* file_name) {return file_operation->vt->open(file_operation, file_name);
}....

总结

适配器模式的思想是把已经存在的功能,由于接口不兼容而不能一起工作时,增加一层包装,使得封装后的接口满足客户系统的需求。

Adapter(适配器)模式总结相关推荐

  1. 设计模式学习之---Adapter(适配器)模式

    1.Adapter适配器模式,是一种接口型模式.它将一个或多个类的接口,转换成客户所期望的接口. 2.它的宗旨是:基于现有类所提供的服务,向客户提供接口,以满足客户的期望. 3.实现:创建一个客户所需 ...

  2. 16Adapter(适配器)模式

    技术交流QQ群:1027579432,欢迎你的加入! 1.Adapter(适配器)模式的动机 在软件系统中,由于应用环境的变化,常常需要将一些现存的对象放在新的环境中应用,但是新环境要求的接口是这些现 ...

  3. Java 设计模式 Adapter 对象适配器 模式

    Java 设计模式 Adapter 对象适配器 模式 Adapter模式用于现有的程序无法直接使用,需要做适当的变换之后才能使用的情况. 涉及到的角色 Target对象:定义所需的方法. Client ...

  4. android中Adapter适配器的讲解

    android中Adapter适配器的讲解 Adapter(适配器的讲解) 适配器就我自己来看,我觉得这是一个非常重要的知识点,Adapter是用来帮助填出数据的中间桥梁,简单点说吧:将各种数据以合适 ...

  5. Adapter适配器与具体应用

    Adapter适配器与具体应用 一.Adapter介绍: 1.Adapter是什么:Adapter适配器是沟通数据与视图的桥梁,用于对要进行显示的数据进行处理, 并通过与视图对象的绑定从而将数据显示到 ...

  6. android 之UI 高级控件Adapter(适配器详解)

    了解适配器组件: 适配器是一个连接数据源和AdapterView的桥梁,通过它能有效的实现数据源与AdapterView的分离设置,使AdaptereView与数据的绑定更加简便,修改更加方便. Ad ...

  7. Adapter适配器和base-adapter-helper库的使用

    文章目录 Adapter适配器 概述 关于视图重用 关于ViewHolder 使用步骤 base-adapter-helper库的使用 1.导入库 2.将库中的java文件复制到项目中 3.编译并解决 ...

  8. Android中使用Adapter(适配器)给RecycleView设置数据源

    场景 RecyclerView RecyclerView是Android一个更强大的控件,其不仅可以实现和ListView同样的效果,还有优化了ListView中的各种不足.其可以实现数据纵向滚动,也 ...

  9. adapter 适配器

    定义: 适配器模式:把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作. 示例: 比如,水货的手机充电器插头是欧美标准(大头插座),中国的插座是 ...

  10. Android适配器以及作用,Android Studio:自定义Adapter(适配器)的一些通俗易懂的理解(以一个简单的聊天界面为例)...

    本文是博主对Adapter(适配器)的一些理解,为了加深对Adapter的理解以及记录自己的阶段学习而写,同时也适合初学者阅读,参考本条博客的逻辑进行学习. 第一  先来看看实现这个程序需要需要创建哪 ...

最新文章

  1. c if 判断select已经选择的值_Golang语言基础教程:if分支语句
  2. VS Code有哪些奇技淫巧?
  3. linux通信中recv,linux套接字通信之recv中的缓存机制的研究
  4. java实现系统多级文件夹复制
  5. 【转载保存】java四种线程池的使用
  6. python decimal 转 float_python教程之二python数学运算
  7. 不能在本地计算机启动 dtc,win10系统dTC服务无法启动的操作技巧
  8. Mac下的Docker及Kubernetes(k8s)本地环境搭建与应用部署、管理界面kubernetes-dashboard
  9. Virtual Box Host-Only网络模式配置
  10. 最短路算法(3种算法)
  11. 吴恩达机器学习 逻辑回归 作业2(芯片预测) Python实现 代码详细解释
  12. 搭载敏捷飞天底座 阿里云专有云敏捷版全面升级 | 凌云时刻
  13. excel自动排班表_18个施工进度计划横道图,Excel版自动生成表,操作简单明了
  14. js去除字符串空格(空白符)
  15. qt.qpa.xcb: could not connect to display解决
  16. opencv 通过标定摄像头测量物体大小_解决方案 | 如何用普通手机准确测量物体体积?...
  17. SQL查询按照特定规则排序
  18. Purism FAQ
  19. 计算机专业押韵口号16字,创新口号16字押韵创新 鼓励创新的标语
  20. 程序员专用显示器,这款性价比超高!

热门文章

  1. NETALLY LRAT-2000/LRAT-1000/LRAT-2000-KIT有线链路通测试仪2020重磅登场
  2. 基于Autocad 2016,与 CASS10 无缝整合的地下管线成图系统
  3. 程序猿面试题:为什么曹操能号令诸侯?
  4. 剑灵显示服务器延迟怎么看,windows7电脑如何查看剑灵延迟
  5. ZYNQ之路--搞清楚Xilinx开发软件之间的关系
  6. PostgreSQL入门基本语法之DDL-(user、database、schema)
  7. opencv入门:支持向量机,K均值聚类
  8. 【CVPR2020】Detection in Crowded Scenes One Proposal Multiple Predictions 翻译
  9. 主动学习(Active Learning)简介综述汇总以及主流技术方案
  10. uniapp仿微信--聊天界面模板