dushaoshuai / dushaoshuai.github.io

https://www.shuai.host
0 stars 0 forks source link

Adapter(Wrapper) #60

Open dushaoshuai opened 1 year ago

dushaoshuai commented 1 year ago

适配器模式使用一个适配器(adapter)包裹另一个类型(adaptee)。adapter 通过调用 adaptee 的方法实现目标接口,而 adaptee 本身没有实现目标接口,他通过 adapter 的这层转换实现目标接口。

http.HandlerFunc

下面来看一个简单的例子。

http.Handler 对 http 请求进行响应。http.Handler 是一个接口:

type Handler interface {
    ServeHTTP(ResponseWriter, *Request)
}

任何实现了 ServeHTTP 方法的类型都实现了 http.Handler 接口。

如果说现在有一个函数 f func(w http.ResponseWriter, req *http.Request) { /* ... */ },f 可以对 http 请求进行响应,但是他无法作为 http.Handler 使用。适配器 http.HandlerFunc 可以将普通函数 f 转化为 http.Handler

type HandlerFunc func(ResponseWriter, *Request)

func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
    f(w, r)
}

在任何需要 http.Handler 的地方,http.HandlerFunc(f) 都是一个合法的值。

可以看到,普通函数被 http.HandlerFunc 包裹后,实现了 http.Handler 接口。

电源适配器

电源适配器是现实世界中的一个适配器例子。输入一个电压,输出一个电压。下面是一个简单的电源适配器类比实现:

package adapter

type V5 interface {
    V5Charge()
}

type V220 struct{}

func NewV220() *V220 {
    return &V220{}
}

func (v220 *V220) V220Charge() {}

type V5Adapter struct {
    v220 *V220
}

func NewV5Adapter(v220 *V220) *V5Adapter {
    return &V5Adapter{
        v220: v220,
    }
}

func (v *V5Adapter) V5Charge() {
    v.v220.V220Charge()
}
type phone struct{}

func (p *phone) charge(adapter.V5) {}

p := new(phone)

p.charge(adapter.NewV5Adapter(adapter.NewV220()))

See also