python 設計模式-適配器模式

問題:假設有一個軟件系統,你但願它能在不改變現有代碼的前提下和一個新的廠商類庫搭配使用,可是這個新廠商所設計出來的接口不一樣於舊廠商的接口

這個問題和下圖的問題相似python

美國標準的插頭🔌沒法在歐洲標準的插座上使用,一般的作法是什麼呢?sql

添加一個插頭適配器,適配器的做用是將歐式插頭轉換成美式插座,以便於讓美式插頭可使用。

解決方案

因此,面對一個有全新接口的類庫而又不能改變現有代碼時,最早想到的作法是,在這兩個系統之間添加一個適配器。數據庫

簡單的例子

有一個系統,須要一個鴨子🦆對象,可是如今只有一個火雞🦃對象。鴨子和火雞對象的功能簡單描述以下:
# 鴨子的簡單描述
class Duck:
    def quack(self):
        # 會呱呱叫
        print("Quack")
    
    def fly(self):
        # 飛的能力
        print("I'm flying")
        
# 火雞的簡單描述
class Turkey:
    def gobble(self):
        # 不會呱呱叫,只會咯咯叫
        print("Gobble gobble")
    
    def fly(self):
        # 飛的能力 可是飛不遠
        print("I'm flying a short distance")

由於如今沒有鴨子對象,只能那火雞對象冒充。因爲鴨子對象和火雞對象功能不一樣,不能直接拿來用,如今就須要使用適配器來完成這個功能:json

class TurkeyAdapter(Duck):
    turkey = Turkey()  # 這裏實際使用的是火雞對象
    
    # 實現鴨子對象擁有的quack方法
    def quack(self):
        self.turkey.gobble()
    
    def fly(self):
        # 假設火雞比鴨子飛的短,爲了模擬鴨子的動做,多飛幾回
        for i in range(5):
            turkey.fly()

接下來調用就能夠像使用鴨子對象同樣使用火雞適配後的對象。小程序

# test

duck = Duck()
duck.quack()
duck.fly()

turkey_adapter = Duck()
turkey_adapter.quack()
turkey_adapter.fly()

如今再來看一下適配器使用的過程:設計模式

  1. 客戶經過被適配者實現的接口調用適配器
  2. 適配器將請求轉換爲被適配者能夠響應的請求
  3. 被適配者響應,把結果返回給適配器,而後適配器再將結果響應給客戶。

經過這個例子,接下來看一下適配器模式的正式定義併發

定義

適配器模式:將一個類的接口,轉換成客戶指望的另外一個接口。適配器讓本來接口不兼容的類能夠合做。

優勢

  • 能夠經過建立適配器進行接口轉換,讓不兼容的接口兼容,讓客戶從實現的接口的解耦。
  • 使用對象組合,以修改的接口包裝被適配者
  • 被適配的子類能夠搭配着適配器使用
  • 知足開放/封閉原則(open/close principle)
開放/封閉原則是面向對象設計的基本原則之一,聲明一個軟件實體應該對擴展是開放的,對修改是關閉的。

真實世界中的適配器

  • xmltodict 能夠將 xml 轉換爲 json
  • grpc 也能夠認爲是一種適配器,提供了跨語言調用能力
  • sqlalchemy 能夠在不改變代碼的狀況下對接多種數據庫
本文例子來自《Head First 設計模式》。

最後,感謝女友支持和包容,比❤️spa

也能夠在公號輸入如下關鍵字獲取歷史文章:公號&小程序 | 設計模式 | 併發&協程設計

相關文章
相關標籤/搜索