一文读懂适配器模式

设计二十三式之适配器

01 意图

适配器是一种结构设计模式,它允许具有不兼容接口的对象进行写作。

image

02 问题

想象一下,您正在创建一个股票市场监控应用程序。该应用程序以 XML 格式从多个来源下载股票数据,然后为用户显示漂亮的图表和图表。

在某些时候,您决定通过集成智能的 3rd 方分析库来改进应用程序。但有一个问题:分析库仅适用于 JSON 格式的数据。

image

您可以更改库以使用 XML。但是,这可能会破坏一些依赖于该库的现有代码。更糟糕的是,您可能一开始就无法访问该库的源代码,从而使这种方法变得不可能。

03 解决方案

您可以创建一个适配器。这是一个特殊的对象,它转换一个对象的接口,以便另一个对象可以理解它。

适配器包装其中一个对象以隐藏在幕后发生的转换的复杂性。被包装的对象甚至不知道适配器。例如,您可以使用将所有数据转换为英制单位(例如英尺和英里)的适配器包装以米和公里为单位的对象。

适配器不仅可以将数据转换为各种格式,还可以帮助具有不同接口的对象进行协作。以下是它的工作原理:

  1. 适配器获得一个与现有对象之一兼容的接口。

  2. 使用此接口,现有对象可以安全地调用适配器的方法。

  3. 接收到调用后,适配器将请求传递给第二个对象,但采用第二个对象所期望的格式和顺序。

有时甚至可以创建一个双向适配器,可以双向转换呼叫。

image

让我们回到我们的股市应用程序。为了解决不兼容格式的困境,您可以为您的代码直接使用的分析库的每个类创建 XML 到 JSON 适配器。然后调整代码以仅通过这些适配器与库进行通信。当适配器接收到调用时,它将传入的 XML 数据转换为 JSON 结构,并将调用传递给包装分析对象的适当方法。

04 举个栗子

image

当您第一次从美国旅行到欧洲时,您可能会在尝试为笔记本电脑充电时感到惊讶。不同国家的电源插头和插座标准不同。这就是为什么您的美国插头不适合德国插座的原因。该问题可以通过使用具有美式插座和欧式插头的电源插头适配器来解决。

05 结构实现

对象适配器:

该实现使用对象组合原理:适配器实现一个对象的接口,包装另一个对象。它可以用所有流行的编程语言实现。

image

类适配器:

此实现使用继承:适配器同时从两个对象继承接口。请注意,这种方法只能在支持多重继承的编程语言中实现,例如 C++。

image

06 伪代码

这个适配器模式的例子是基于方钉和圆孔之间的经典冲突。

image

Adapter 伪装成一个圆形钉子,半径等于正方形直径的一半(换句话说,可以容纳方形钉子的最小圆的半径)。

// Say you have two classes with compatible interfaces:
// RoundHole and RoundPeg.
class RoundHole is
    constructor RoundHole(radius) { ... }

    method getRadius() is
        // Return the radius of the hole.

    method fits(peg: RoundPeg) is
        return this.getRadius() >= peg.getRadius()

class RoundPeg is
    constructor RoundPeg(radius) { ... }

    method getRadius() is
        // Return the radius of the peg.


// But there's an incompatible class: SquarePeg.
class SquarePeg is
    constructor SquarePeg(width) { ... }

    method getWidth() is
        // Return the square peg width.


// An adapter class lets you fit square pegs into round holes.
// It extends the RoundPeg class to let the adapter objects act
// as round pegs.
class SquarePegAdapter extends RoundPeg is
    // In reality, the adapter contains an instance of the
    // SquarePeg class.
    private field peg: SquarePeg

    constructor SquarePegAdapter(peg: SquarePeg) is
        this.peg = peg

    method getRadius() is
        // The adapter pretends that it's a round peg with a
        // radius that could fit the square peg that the adapter
        // actually wraps.
        return peg.getWidth() * Math.sqrt(2) / 2


// Somewhere in client code.
hole = new RoundHole(5)
rpeg = new RoundPeg(5)
hole.fits(rpeg) // true

small_sqpeg = new SquarePeg(5)
large_sqpeg = new SquarePeg(10)
hole.fits(small_sqpeg) // this won't compile (incompatible types)

small_sqpeg_adapter = new SquarePegAdapter(small_sqpeg)
large_sqpeg_adapter = new SquarePegAdapter(large_sqpeg)
hole.fits(small_sqpeg_adapter) // true
hole.fits(large_sqpeg_adapter) // false

07 优缺点

image

欢迎查看公众号内容:
https://mp.weixin.qq.com/s?__biz=Mzk0NjI5NzE1Ng==&mid=2247483682&idx=1&sn=6c9b3f3fc8a997030efb917231e11905&chksm=c3090109f47e881f32292dd6af09d3eea5d094aeb075f69a916b411a3de6ba4d014d1e05b9a1#rd

关注公众号可获取干货资料:《设计模式详解》


image.png

image.png
image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,163评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,301评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,089评论 0 352
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,093评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,110评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,079评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,005评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,840评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,278评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,497评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,394评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,980评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,628评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,649评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,548评论 2 352

推荐阅读更多精彩内容