Menu

  • Home
  • Work
    • Cloud
      • Virtualization
      • IaaS
      • PaaS
    • Java
    • Go
    • C
    • C++
    • JavaScript
    • PHP
    • Python
    • Architecture
    • Others
      • Assembly
      • Ruby
      • Perl
      • Lua
      • Rust
      • XML
      • Network
      • IoT
      • GIS
      • Algorithm
      • AI
      • Math
      • RE
      • Graphic
    • OS
      • Linux
      • Windows
      • Mac OS X
    • BigData
    • Database
      • MySQL
      • Oracle
    • Mobile
      • Android
      • IOS
    • Web
      • HTML
      • CSS
  • Life
    • Cooking
    • Travel
    • Gardening
  • Gallery
  • Video
  • Music
  • Essay
  • Home
  • Work
    • Cloud
      • Virtualization
      • IaaS
      • PaaS
    • Java
    • Go
    • C
    • C++
    • JavaScript
    • PHP
    • Python
    • Architecture
    • Others
      • Assembly
      • Ruby
      • Perl
      • Lua
      • Rust
      • XML
      • Network
      • IoT
      • GIS
      • Algorithm
      • AI
      • Math
      • RE
      • Graphic
    • OS
      • Linux
      • Windows
      • Mac OS X
    • BigData
    • Database
      • MySQL
      • Oracle
    • Mobile
      • Android
      • IOS
    • Web
      • HTML
      • CSS
  • Life
    • Cooking
    • Travel
    • Gardening
  • Gallery
  • Video
  • Music
  • Essay

适配器模式

11
Oct
2006

适配器模式

By Alex
/ in Architecture
/ tags 设计模式
0 Comments
模式定义

适配器模式将一个类的接口,转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以无缝协作。在GOF95中,适配器被分类为结构型模式。适配器和装饰器具有共同的别名:Wrapper。

模式结构与说明

对象适配器:使用单重继承+组合,类图如下:

patterns_AdaptorPattern

类适配器:使用多重继承,可能需要支持多继承的语言(例如C++、Python),类图如下:

patterns_AdaptorPattern_Class

  1. Client只能看到期望的目标接口,不知道接口居然是李鬼
  2. Adaptor需要实现目标接口,同时与Adaptee形成组合关系,转调Adaptee来实现目标接口中的方法
  3. Adaptor一般把操作都委托给Adaptee
  4. Adaptee的任何子类型都可以和Adaptor配合使用
  5. 对象适配器使用单重继承+组合来实现适配。类适配器则通过多重继承,Adaptor同时继承Target、Adaptee,并通过转调父类方法来进行适配。

其实生活中有大量适配器的例子。例如,香港的插座规格与大陆不一样,为了能在香港出差时正常使用笔记本电脑,你可能需要携带一个插座转换头,这个转换头就是一个适配器,笔记本电脑的变压器也是典型的例子,它把市电220V交流电转换为18.3V的直流电。

适配器模式与装饰模式在形式上很类似,都是包装一个对象。但适配器是改变接口,而装饰器则是添加功能。

适配器模式的优点:

  1. 类适配器可以在必要时覆盖Adaptee的方法,用以降低适配工作量

适配器模式的缺点:

  1. 如果被适配者的接口规模很大,那么适配器的规模也相应变大
  2. 类适配器模式缺乏灵活性,不能动态的改变Adaptee

适配器模式的适用时机:

  1. 想使用一个已经存在的类,但是它的接口不符合需求
  2. 向创建一个可复用的类,该类可以与其它不相关的、不可预见的(即接口不一定兼容)的类协同工作
应用举例
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>
using namespace std;
/* 鸭子 */
class Duck
{
    public:
        virtual void quack()
        {
            cout << "Quack quack, too hot, me die." << endl;
        }
}
/* 鸡 */
class Chicken
{
    public:
        virtual void croak()
        {
            cout << "Crock crock, I'm not a duck, let me go!" << endl;
        }
        void shutup()
        {
        }
};
/* 烤活鸭炉 */
class AliveDuckOven
{
    public:
        void roast( Duck* duck )
        {
            duck->quack(); //鸭子惨叫一声
        }
};
/* 粘上鸭毛的鸡 */
class FakeDuck : public Duck, public Chicken
{
    public:
        virtual void quack()
        {
            Duck.quack();
        }
};
 
int main( int argc, char **argv )
{
    //老妖婆有一个烤炉
    AliveDuckOven oven;
    //她每天都要村民进贡一只活鸭烤熟
    Duck littleDuck;
    oven.roast( &littleDuck );
    //村里的鸭子被吃光了,如果不给老妖婆进贡,她将每天杀死一个小孩
    //村里有很多鸡,村民想了个好主意,把鸡粘上鸭毛
    FakeDuck chickenWithDuckFeather = new FakeDuck();
    //闭嘴,你这只笨鸡
    chickenWithDuckFeather.shutup();
    //像鸭子一样叫吧
    chickenWithDuckFeather.quack();
    //老妖婆就把这只粘上鸭毛的鸡烤着吃了
    oven.roast( &chickenWithDuckFeather );
}
经典应用
JDBC与ODBC

JDBC即Java DataBase Connectivity,它让所有Java应用程序通过一致性的接口来访问数据库,屏蔽了不同厂商的差异性:

patterns_AdaptorPattern_JDBC

数据库厂商负责实现JDBC接口(即Target接口族),并对自己私有的数据库对象进行适配,这些数据库对象的形式是五花八门的。

微软的ODBC与JDBC的想法很类似,在没有JDBC实现的情况下,Java可以通过JDBC/ODBC桥来连接数据库,JDBC和ODBC的接口是不同的,因此JDBC/ODBC桥也是适配器模式的应用。

Java I/O

JDK I/O包中不但有很多装饰模式,也有不少适配器模式的实现,例如:

Java
1
2
java.io.InputStreamReader(InputStream);
java.io.OutputStreamWriter(OutputStream);

可以将字节流接口转换为字符流接口。 

Cygwin与Wine

Cygwin和Wine这两种工具都是在架构层次上提现出适配器模式的例子。Cygwin用于在Windows环境下编译、运行基于Linux API的应用程序;Wine则用于在Linux下不加修改的运行Windows应用程序。这两种工具都在底层代码上做了大量的适配工作。

模式演变
  1. 适配多个Adaptee,某些情况下需要使用多个Adaptee才能实现Target中的功能
  2. 智能适配器:Adaptor实现一些Adaptee没有实现,但是Target中定义的功能
  3. 缺省适配:为接口提供一个默认的实现,有了它,就不用去直接实现接口,而继承此缺省适配类就可以了,可以减少代码量
  4. 双向适配器:同时实现Target、Adaptee规定的接口
← Linux IO知识集锦
外观模式 →

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

Related Posts

  • 代理模式
  • 命令模式
  • 中介者模式
  • 外观模式
  • 策略模式

Recent Posts

  • Investigating and Solving the Issue of Failed Certificate Request with ZeroSSL and Cert-Manager
  • A Comprehensive Study of Kotlin for Java Developers
  • 背诵营笔记
  • 利用LangChain和语言模型交互
  • 享学营笔记
ABOUT ME

汪震 | Alex Wong

江苏淮安人,现居北京。目前供职于腾讯云,专注容器方向。

GitHub:gmemcc

Git:git.gmem.cc

Email:gmemjunk@gmem.cc@me.com

ABOUT GMEM

绿色记忆是我的个人网站,域名gmem.cc中G是Green的简写,MEM是Memory的简写,CC则是我的小天使彩彩名字的简写。

我在这里记录自己的工作与生活,同时和大家分享一些编程方面的知识。

GMEM HISTORY
v2.00:微风
v1.03:单车旅行
v1.02:夏日版
v1.01:未完成
v0.10:彩虹天堂
v0.01:阳光海岸
MIRROR INFO
Meta
  • Log in
  • Entries RSS
  • Comments RSS
  • WordPress.org
Recent Posts
  • Investigating and Solving the Issue of Failed Certificate Request with ZeroSSL and Cert-Manager
    In this blog post, I will walk ...
  • A Comprehensive Study of Kotlin for Java Developers
    Introduction Purpose of the Study Understanding the Mo ...
  • 背诵营笔记
    Day 1 Find Your Greatness 原文 Greatness. It’s just ...
  • 利用LangChain和语言模型交互
    LangChain是什么 从名字上可以看出来,LangChain可以用来构建自然语言处理能力的链条。它是一个库 ...
  • 享学营笔记
    Unit 1 At home Lesson 1 In the ...
  • K8S集群跨云迁移
    要将K8S集群从一个云服务商迁移到另外一个,需要解决以下问题: 各种K8S资源的迁移 工作负载所挂载的数 ...
  • Terraform快速参考
    简介 Terraform用于实现基础设施即代码(infrastructure as code)—— 通过代码( ...
  • 草缸2021
    经过四个多月的努力,我的小小荷兰景到达极致了状态。

  • 编写Kubernetes风格的APIServer
    背景 前段时间接到一个需求做一个工具,工具将在K8S中运行。需求很适合用控制器模式实现,很自然的就基于kube ...
  • 记录一次KeyDB缓慢的定位过程
    环境说明 运行环境 这个问题出现在一套搭建在虚拟机上的Kubernetes 1.18集群上。集群有三个节点: ...
  • eBPF学习笔记
    简介 BPF,即Berkeley Packet Filter,是一个古老的网络封包过滤机制。它允许从用户空间注 ...
  • IPVS模式下ClusterIP泄露宿主机端口的问题
    问题 在一个启用了IPVS模式kube-proxy的K8S集群中,运行着一个Docker Registry服务 ...
  • 念爷爷
      今天是爷爷的头七,十二月七日、阴历十月廿三中午,老人家与世长辞。   九月初,回家看望刚动完手术的爸爸,发

  • 6 杨梅坑

  • liuhuashan
    深圳人才公园的网红景点 —— 流花山

  • 1 2020年10月拈花湾

  • 内核缺陷触发的NodePort服务63秒延迟问题
    现象 我们有一个新创建的TKE 1.3.0集群,使用基于Galaxy + Flannel(VXLAN模式)的容 ...
  • Galaxy学习笔记
    简介 Galaxy是TKEStack的一个网络组件,支持为TKE集群提供Overlay/Underlay容器网 ...
TOPLINKS
  • Zitahli's blue 91 people like this
  • 梦中的婚礼 64 people like this
  • 汪静好 61 people like this
  • 那年我一岁 36 people like this
  • 为了爱 28 people like this
  • 小绿彩 26 people like this
  • 杨梅坑 6 people like this
  • 亚龙湾之旅 1 people like this
  • 汪昌博 people like this
  • 彩虹姐姐的笑脸 24 people like this
  • 2013年11月香山 10 people like this
  • 2013年7月秦皇岛 6 people like this
  • 2013年6月蓟县盘山 5 people like this
  • 2013年2月梅花山 2 people like this
  • 2013年淮阴自贡迎春灯会 3 people like this
  • 2012年镇江金山游 1 people like this
  • 2012年徽杭古道 9 people like this
  • 2011年清明节后扬州行 1 people like this
  • 2008年十一云龙公园 5 people like this
  • 2008年之秋忆 7 people like this
  • 老照片 13 people like this
  • 火一样的六月 16 people like this
  • 发黄的相片 3 people like this
  • Cesium学习笔记 90 people like this
  • IntelliJ IDEA知识集锦 59 people like this
  • Bazel学习笔记 38 people like this
  • 基于Kurento搭建WebRTC服务器 38 people like this
  • PhoneGap学习笔记 32 people like this
  • NaCl学习笔记 32 people like this
  • 使用Oracle Java Mission Control监控JVM运行状态 29 people like this
  • Ceph学习笔记 27 people like this
  • 基于Calico的CNI 27 people like this
  • Three.js学习笔记 24 people like this
Tag Cloud
ActiveMQ AspectJ CDT Ceph Chrome CNI Command Cordova Coroutine CXF Cygwin DNS Docker eBPF Eclipse ExtJS F7 FAQ Groovy Hibernate HTTP IntelliJ IO编程 IPVS JacksonJSON JMS JSON JVM K8S kernel LB libvirt Linux知识 Linux编程 LOG Maven MinGW Mock Monitoring Multimedia MVC MySQL netfs Netty Nginx NIO Node.js NoSQL Oracle PDT PHP Redis RPC Scheduler ServiceMesh SNMP Spring SSL svn Tomcat TSDB Ubuntu WebGL WebRTC WebService WebSocket wxWidgets XDebug XML XPath XRM ZooKeeper 亚龙湾 单元测试 学习笔记 实时处理 并发编程 彩姐 性能剖析 性能调优 文本处理 新特性 架构模式 系统编程 网络编程 视频监控 设计模式 远程调试 配置文件 齐塔莉
Recent Comments
  • qg on Istio中的透明代理问题
  • heao on 基于本地gRPC的Go插件系统
  • 黄豆豆 on Ginkgo学习笔记
  • cloud on OpenStack学习笔记
  • 5dragoncon on Cilium学习笔记
  • Archeb on 重温iptables
  • C/C++编程:WebSocketpp(Linux + Clion + boostAsio) – 源码巴士 on 基于C/C++的WebSocket库
  • jerbin on eBPF学习笔记
  • point on Istio中的透明代理问题
  • G on Istio中的透明代理问题
  • 绿色记忆:Go语言单元测试和仿冒 on Ginkgo学习笔记
  • point on Istio中的透明代理问题
  • 【Maven】maven插件开发实战 – IT汇 on Maven插件开发
  • chenlx on eBPF学习笔记
  • Alex on eBPF学习笔记
  • CFC4N on eBPF学习笔记
  • 李运田 on 念爷爷
  • yongman on 记录一次KeyDB缓慢的定位过程
  • Alex on Istio中的透明代理问题
  • will on Istio中的透明代理问题
  • will on Istio中的透明代理问题
  • haolipeng on 基于本地gRPC的Go插件系统
  • 吴杰 on 基于C/C++的WebSocket库
©2005-2025 Gmem.cc | Powered by WordPress | 京ICP备18007345号-2