1. 程式人生 > >golang設計模式(6)介面卡模式

golang設計模式(6)介面卡模式

介面卡模式設計意圖
將一個型別的介面轉換成客戶希望的另外一個介面,使原本由於介面不相容而不能一起工作的類可以一起工作。

適用性
.想適用一個已經存在的型別,而其介面不符合需求
.建立一個可以複用的型別,該型別可以與其他不相關的型別或不可預見的型別協同工作。
.(僅適用於物件Adapter)想使用一些已經存在的子類,但是不可能對每個子類修改為匹配他們的介面,物件介面卡可以適配它的父類介面。

結構(uml)
介面卡模式

介面卡模式的型別
介面卡可以分為型別介面卡和物件介面卡。
對於型別介面卡:
.用一個具體的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。兩者具有一點的相似性。當系統不想保留介面的時候,就可以用介面卡來修飾。