设计模式——适配器

135 阅读2分钟

引言

在现实世界,如果你有一台电视机,是一个二孔插头,然后插排是一个三孔插排,你会怎么做呢?

  • 方法一:将耳孔插头掰一掰,让它能够插入到三孔插排中(过于暴力,不推荐)
  • 方法二:加入一个三孔转二孔的转换器,如下图所示:

UML图

对应于计算机世界来说,适配器的作用是接口协议的转换。看下面的UML图,我们的客户端client,需要一个调用reqeust接口,但是,我们使用的对象Adaptee,仅仅只有方法specificRequest,因此,clien不能直接调用Adaptee的方法,需要通过适配器Adapter包一层,进行协议的转换。

这么说,可能过于抽象,我们看下面这个例子,再看具体代码之前,我们先统一下语言:

  • TriplePin:表示三孔插排;
  • TV:是一个 两孔插头的电视机;
  • AdapterTriple:是一个转换器;

我们的目的,就是将电视机插入到三孔插排中,所以需要通过AdapterTriple将两孔转为三孔。来看下具体代码实现;

适配器代码

package system_design

import (
    "fmt"
    "testing"
)

// TriplePin 三孔接口
type TriplePin interface {
    electrify(a, b, c int) error
}

// 两孔接口
type DualPin interface {
    electrify(a, b int) error
}

// TV是一个两孔接口
type TV struct{}

func (T TV) electrify(a, b int) error {
    fmt.Printf("电视的零线与火线, a:[%v], b:[%v]", a, b)
    return nil
}

type AdapterTriple struct {
    adaptee DualPin
}

func (a2 AdapterTriple) electrify(a, b, c int) error {
    a2.adaptee.electrify(a, b)
    return nil
}

func TestAdapter(t *testing.T) {
    // 创建TV
    tv := TV{}

    // 三孔插头
    var triple TriplePin

    // 两孔电视机连不上三孔插头,会报错
    // triple = tv

    // 将电视插在适配器上,然后连上三孔插头
    triple = AdapterTriple{tv}

    // 通电
    triple.electrify(1, 2, 3)
}

参考

  • 秒懂设计模式
  • 图解设计模式