9.設計模式之七:適配器模式【結構型模式】

在現實生活中,常常出現兩個對象因接口不兼容而不能在一塊兒工做的實例,這時須要第三者進行適配。python

例如,講中文的人同講英文的人對話時須要一個翻譯,用直流電的筆記本電腦接交流電源時須要一個電源適配器,用計算機訪問照相機的 SD 內存卡時須要一個讀卡器等。程序員

在軟件設計中也可能出現:須要開發的具備某種業務功能的組件在現有的組件庫中已經存在,但它們與當前系統的接口規範不兼容,若是從新開發這些組件成本又很高,這時用適配器模式能很好地解決這些問題。spa

定義與特色

適配器模式(Adapter)的定義以下:將一個類的接口轉換成客戶但願的另一個接口,使得本來因爲接口不兼容而不能一塊兒工做的那些類能一塊兒工做。翻譯

適配器模式分爲類結構型模式和對象結構型模式兩種,前者類之間的耦合度比後者高,且要求程序員瞭解現有組件庫中的相關組件的內部結構,因此應用相對較少些。設計

該模式的主要優勢以下。3d

  • 客戶端經過適配器能夠透明地調用目標接口。
  • 複用了現存的類,程序員不須要修改原有代碼而重用現有的適配者類。
  • 將目標類和適配者類解耦,解決了目標類和適配者類接口不一致的問題。

其缺點是:對類適配器來講,更換適配器的實現過程比較複雜。code

結構與實現

類適配器模式 可採用多重繼承方式實現,如 C++ 可定義一個適配器類來同時繼承當前系統的業務接口和現有組件庫中已經存在的組件接口;Java 不支持多繼承,但能夠定義一個適配器類來實現當前系統的業務接口,同時又繼承現有組件庫中已經存在的組件。對象

對象適配器模式 可釆用將現有組件庫中已經實現的組件引入適配器類中,該類同時實現當前系統的業務接口。如今來介紹它們的基本結構。blog

1. 模式的結構

適配器模式(Adapter)包含如下主要角色。繼承

  1. 目標(Target)接口:當前系統業務所期待的接口,它能夠是抽象類或接口。
  2. 適配者(Adaptee)類:它是被訪問和適配的現存組件庫中的組件接口。
  3. 適配器(Adapter)類:它是一個轉換器,經過繼承或引用適配者的對象,把適配者接口轉換成目標接口,讓客戶按目標接口的格式訪問適配者。

類適配器模式的結構圖如圖所示

對象適配器模式的結構圖如圖所示

2. 模式的實現

類適配器模式的代碼以下

class Target(object):
    def request(self):
        pass

class Adaptee(object):
    def specific_request(self):
        print("適配器代碼被調用")

class Adapter(Adaptee, Target):
    def request(self):
        self.specific_request()

if __name__ == '__main__':
    t = Adapter()
    t.request()

對象適配器模式的代碼以下

class Target(object):
    def request(self):
        pass

class Adaptee(object):
    def specific_request(self):
        print("適配器代碼被調用")

class Adapter(Target):
    __adaptee = None
    def __init__(self, adaptee):
        self.__adaptee = adaptee

    def request(self):
        self.__adaptee.specific_request()


if __name__ == '__main__':
    adaptee = Adaptee()
    t = Adapter(adaptee)
    t.request()

應用實例

例1】用適配器模式(Adapter)模擬新能源汽車的發動機。

分析:新能源汽車的發動機有電能發動機(Electric Motor)和光能發動機(Optical Motor)等,各類發動機的驅動方法不一樣,例如,電能發動機的驅動方法 electricDrive() 是用電能驅動,而光能發動機的驅動方法 opticalDrive() 是用光能驅動,它們是適配器模式中被訪問的適配者。

客戶端但願用統一的發動機驅動方法 drive() 訪問這兩種發動機,因此必須定義一個統一的目標接口 Motor,而後再定義電能適配器(Electric Adapter)和光能適配器(Optical Adapter)去適配這兩種發動機。

class Motor(object):
    def driver(self):
        pass

class ElectricMotor(object):
    def electric_driver(self):
        print('electric_driver')

class OpticalMotor(object):
    def optical_driver(self):
        print('optical_driver')

class ElectricAdapter(Motor):
    def __init__(self):
        self.__motor = ElectricMotor()

    def driver(self):
        self.__motor.electric_driver()

class OpticalAdapter(Motor):
    def __init__(self):
        self.__motor = OpticalMotor()

    def driver(self):
        self.__motor.optical_driver()

if __name__ == '__main__':
    em = ElectricAdapter()
    em.driver()

    om = OpticalAdapter()
    om.driver()

應用場景

適配器模式(Adapter)一般適用於如下場景。

  • 之前開發的系統存在知足新系統功能需求的類,但其接口同新系統的接口不一致。
  • 使用第三方提供的組件,但組件接口定義和本身要求的接口定義不一樣。

模式的擴展

適配器模式(Adapter)可擴展爲雙向適配器模式,雙向適配器類既能夠把適配者接口轉換成目標接口,也能夠把目標接口轉換成適配者接口,其結構圖如圖所示。

class TwoWayTarget(object):
    def request(self):
        pass

class TwoWayAdaptee(object):
    def specific_request(self):
        pass

class TargetRealize(TwoWayTarget):
    def request(self):
        print("目標代碼被調用")

class AdapteeRealize(TwoWayAdaptee):
    def specific_request(self):
        print("適配者代碼被調用")

class TwoWayAdapter(TwoWayTarget, TwoWayAdaptee):
    __adaptee = None
    __target = None
    def __init__(self, twoway):
        if type(twoway) == AdapteeRealize:
            self.__adaptee = twoway

        elif type(twoway) == TargetRealize:
            self.__target = twoway

    def request(self):
        self.__target.request()

    def specific_request(self):
        self.__adaptee.specific_request()

if __name__ == '__main__':
    adaptee = AdapteeRealize()
    target = TargetRealize()

    twa_ad = TwoWayAdapter(adaptee)
    twa_ad.specific_request()

    twa_ta = TwoWayAdapter(target)
    twa_ta.request()
相關文章
相關標籤/搜索