golang设计模式(6)适配器模式

适配器模式设计意图
将一个类型的接口转换成客户希望的另外一个接口,使原本由于接口不兼容而不能一起工作的类可以一起工作。

适用性
.想适用一个已经存在的类型,而其接口不符合需求
.创建一个可以复用的类型,该类型可以与其他不相关的类型或不可预见的类型协同工作。
.(仅适用于对象Adapter)想使用一些已经存在的子类,但是不可能对每个子类修改为匹配他们的接口,对象适配器可以适配它的父类接口。

结构(uml)
golang设计模式(6)适配器模式_第1张图片

适配器模式的类型
适配器可以分为类型适配器和对象适配器。
对于类型适配器:
.用一个具体的adapter类对adaptee和target进行匹配。结果是当我们想要匹配一个类及它的所有子类时,类adapter将无法胜任工作。
.类适配器可以使adapter重定义adptee的部分行为,因为adapter是adaptee的子类
.仅仅引入一个对象,并不需要额外的指针间接得到adaptee

对应对象适配器:
.对象适配器允许一个adapter和多个adaptee,即多个adaptee及其子类一起工作。
.对象适配器可能在重用方面会比较差,因为可以使用到的是adaptee的子类而不是adaptee本身。

总之,使用适配器,最重要的考虑因素为两个接口的相似程度,没有理由去适配两个毫无关联的接口。

golang实现

package main
import (
    "fmt"
)

type OldInterface interface {
    InsertToDatabase(Data interface{}) (bool, error)
}

type AddCustomInfoToMysql struct {
    DbName string
}

func (pA *AddCustomInfoToMysql) InsertToDatabase(info interface{}) (bool, error) {
    switch info.(type) {
    case string:
        fmt.Println("add ", info.(string), " to ", pA.DbName, " successful!")
    }
    return true, nil
}

type NewInterface interface {
    SaveData(Data interface{}) (bool, error)
}

type Adapter struct {
    OldInterface
}

func (pA *Adapter) SaveData(Data interface{}) (bool, error) {
    fmt.Println("In Adapter")
    return pA.InsertToDatabase(Data)
}

func main() {

    var iNew NewInterface
    iNew = &Adapter{OldInterface: &AddCustomInfoToMysql{DbName: "mysql"}}
    iNew.SaveData("helloworld")
    return
}

从实现例子可以看出,老接口方法为InsertToDatabase,新接口方法为SaveData。两者具有一点的相似性。当系统不想保留接口的时候,就可以用适配器来修饰。

你可能感兴趣的:(go语言,设计模式,设计模式,golang)