結構型設計模式設計模式
結構型設計模式處理一個系統中不一樣實體(好比,類和對象)之間的關係,關注的是提供一種簡單的對象組合方式來創造新功能。
適配器模式app
適配器模式是一種結構型設計模式,幫助咱們實現兩個不兼容接口之間的兼容。首先,解釋一下不兼容接口之間的真正含義。若是咱們但願把一個老組件用於一個新系統中,或者把一個新組件用於一個老系統中,不對代碼進行任何修改就能通訊的狀況不多見。
但又並不是老是能修改代碼,或由於咱們沒法訪問這些代碼(例如,組件之外部庫的方式提供)。在這些狀況下,咱們能夠編寫一個額外的代碼層,該代碼層包含讓兩個接口之間可以通訊須要進行的全部修改。這個代碼層就叫適配器。
生活中的例子:若是你有一部智能手機或一臺平板電腦,在想把它鏈接到你的電腦上,就須要使用一個適配器。
應用案例: 在某個產品製造出來以後,須要對新的需求之時,若是但願其仍然有效,則可使用適配器模式。一般兩個不兼容接口中的一個是他方的或是老舊的。
若是一個接口是他方的,那就意味着沒法訪問源碼。若是是老舊的,那麼對其重構一般是不切實際的。更進一步,咱們能夠說修改一個老舊組件的實現
以知足咱們的需求,不只是不切實際的,也違反了開放/封閉原則。開放/封閉原則是面向對象設計的基本原則之一,聲明一個軟件實體應該對擴展是開
放的,對修改則是封閉的。本質上這意味着咱們應該無需修改一個軟件實體的源代碼就能擴展其行爲。適配器模式聽從開放/封閉原則。
#咱們的應用有一個Computer類,用來顯示一臺計算機的基本信息。咱們決定用更多的功能來豐富應用,咱們很幸運地在兩個與咱們應用無關的代碼庫中發現兩個有意思的類,Synthesizer和Human。
#在Synthesizer類中,主要動做由play()方法執行。在Human類中,主要動做由speak()執行。爲了代表這兩個類是外部的,將其放在一個單獨的模塊中。
如今有一個問題,客戶端僅知道如何調用execute()方法,並不知道play()和speak()。在不改變Synthesizer和Human的前提下,咱們該如何作才能讓代碼有效?
#答案是在test.py中建立一個通用的Adapter類,將一些不一樣接口的對象適配到統一的接口中。
#Computer類 在test.py文件中 class Computer: def __init__(self,name): self.name = name def __str__(self): return 'the {} computer'.format(self.name) def execute(self): return 'executes a program'
#在external.py文件中 class Synthesizer: def __init__(self,name): self.name = name def __str__(self): return 'the {} synthesizer'.format(self.name) def play(self): return 'is playing an electronic song' class Human: def __init__(self,name): self.name = name def __str__(self): return '{} the human'.format(self.name) def speak(self): return 'says hello'
#增長適配器後的test.py文件 from external import Synthesizer,Human class Computer: def __init__(self,name): self.name = name def __str__(self): return 'the {} computer'.format(self.name) def execute(self): return 'executes a program' #建立適配器類 class Adapter: #obj使咱們想要適配的對象,adapted_methods是一個字典, # 鍵值對中的鍵是客戶端要調用的方法,值是應該被調用的方法 def __init__(self,obj,adapted_methods): self.obj = obj self.__dict__.update(adapted_methods) def __str__(self): return str(self.obj) def main(): #列表objects容納着全部對象。屬於Computer類的可兼容對象不須要適配 #不兼容的對象則不能直接添加,使用Adapter類來適配它們。 objects = [Computer('Asus')] synth = Synthesizer('moog') objects.append(Adapter(synth,dict(execute=synth.play))) human = Human('Bob') objects.append(Adapter(human,dict(execute=human.speak))) for i in objects: print('{} {}'.format(str(i),i.execute())) if __name__ == '__main__': main()
小結electron
適配器讓一件產品在製造出來以後須要應對新的需求時還能工做。在上面的例子中,咱們看到如何使用適配器模式,無需修改不兼容模型的源代碼就能得到接口的一致性。雖然在Python中咱們能夠沿襲傳統方式使用子類(繼承)來實現適配器模式,可是這種技術是一種很棒的替代方案。