設計模式是軟體開發中常見問題的經過驗證的解決方案。它們為解決設計問題提供了可重複使用的模板,從而提高了程式碼的可維護性和靈活性。
但是有這麼多可用的設計模式,您如何知道針對給定問題在 Python 中實現哪一種?在本文中,我們將探討選擇正確設計模式的步驟,並提供每個範例,以幫助您理解並有效應用它們。
選擇設計模式的第一步是清楚了解您要解決的問題。問自己以下問題:
預期的行為是什麼?
系統有哪些限制?
可能的延伸或變化點有哪些?
設計模式一般分為三類:
創造:專注於物件的創建。
結構:關注對象的組成。
行為:關注物件之間的互動。
確定與您的問題相符的類別有助於縮小相關模式的數量。
了解問題及其類別後,請查看該類別中的設計模式以找到最適合您情況的設計模式。考慮以下幾點:
靈活性:該模式是否提供必要的彈性?
複雜性:這不會帶來不必要的複雜性嗎?
可擴展性:它是否使未來的擴展更容易?
Python 範例:
`class SingletonMeta(類型):
_instance = {}
def __call__(cls, *args, **kwargs): if cls not in cls._instance: cls._instance[cls] = super().__call__(*args, **kwargs) return cls._instance[cls]
類別 Logger(metaclass=SingletonMeta):
def log(自我, 訊息):
print(f"[LOG]: {訊息}")
logger1 = Logger()
logger2 = Logger()
print(logger1 is logger2) # 輸出:True
logger1.log(“運行中的單例模式。”)
`
為什麼它有效?
SingletonMeta 是一個控制 Logger 實例所建立的元類別。如果實例已存在,則傳回該實例,確保只有一個實例。
工廠
什麼時候使用它?
當您有一個包含多個子類的父類,並且根據輸入數據,您需要返回其中一個子類。
Python 範例:
`類形狀:
def 繪製(自身):
通過
類圓形(形狀):
def 繪製(自身):
print("畫圓。")
類別正方形(形狀):
def 繪製(自身):
print("畫一個正方形。")
def shape_factory(shape_type):
如果 shape_type == "圓":
返回圓()
elif shape_type == "方形":
返回 Square()
其他:
raise ValueError("未知的形狀類型。")
shape = shape_factory("圓")
shape.draw() # 輸出:畫一個圓。
`
為什麼它有效?
工廠封裝了物件創建邏輯,允許在不暴露底層邏輯的情況下建立實例。
觀察
什麼時候使用它?
當你有一個物件(主體)需要在狀態改變時通知多個其他物件(觀察者)。
Python 範例:
`課程主題:
def init(self):
self._observers = []
def __call__(cls, *args, **kwargs): if cls not in cls._instance: cls._instance[cls] = super().__call__(*args, **kwargs) return cls._instance[cls]
類觀察者:
def 更新(自我,訊息):
通過
類別 EmailObserver(觀察者):
def 更新(自我,訊息):
print(f"郵件通知:{message}")
類 SMSObserver(觀察者):
def 更新(自我,訊息):
print(f"簡訊通知:{message}")
主題=主題()
subject.attach(EmailObserver())
subject.attach(SMSObserver())
subject.notify("觀察者模式已實作。")
`
為什麼它有效?
主體維護觀察者列表並通知他們變化,從而允許解耦通訊。
策略
什麼時候使用它?
當您有多種演算法來執行一項任務並且您想要動態地交換它們時。
Python 範例:
`導入類型
類文字處理器:
def init(自身,格式化程式):
self.formatter = types.MethodType(formatter, self)
def attach(self, observer): self._observers.append(observer) def notify(self, message): for observer in self._observers: observer.update(message)
def uppercase_formatter(self, text):
return text.upper()
def lowercase_formatter(self, text):
return text.lower()
處理器 = TextProcessor(uppercase_formatter)
print(processor.process("Hello World")) # 輸出:HELLO WORLD
processor.formatter = types.MethodType(lowercase_formatter, 處理器)
print(processor.process("Hello World")) # 輸出:hello world
`
為什麼它有效?
策略模式可讓您透過為格式指派新函數來動態變更物件使用的演算法。
裝飾器
什麼時候使用它?
當您想要動態地為物件新增功能而不變更其結構時。
Python 範例:
`def bold_decorator(func):
def 包裝器():
return "" func() ""
返回包裝
def italic_decorator(func):
def 包裝器():
return "" func() ""
返回包裝
@bold_decorator
@italic_decorator
def say_hello():
回「你好」
print(say_hello()) # 輸出:你好
`
它為什麼有效?
裝飾器可讓您包裝函數以添加功能,例如在此處進行格式化,而無需修改原始函數。
適應
什麼時候使用它?
當您需要使用現有的類別但其介面不符合您的需求。
Python 範例:
`class EuropeanSocketInterface:
定義電壓(自身):透過
def live(self): 通過
def 中立(自我):透過
類別EuropeanSocket(EuropeanSocketInterface):
定義電壓(自身):
返回230
def __call__(cls, *args, **kwargs): if cls not in cls._instance: cls._instance[cls] = super().__call__(*args, **kwargs) return cls._instance[cls]
USASocketInterface 類別:
定義電壓(自身):透過
def live(self): 通過
def 中立(自我):透過
類別適配器(USASocketInterface):
def init(self, european_socket):
self.european_socket = european_socket
def attach(self, observer): self._observers.append(observer) def notify(self, message): for observer in self._observers: observer.update(message)
euro_socket = EuropeanSocket()
適配器 = 適配器(euro_socket)
print(f"電壓:{adapter.Voltage()}V") # 輸出:電壓:110V
`
適配器將一個類別的接口轉換為客戶端期望的另一個接口,從而允許不相容的接口之間相容。
指令
什麼時候使用它?
當您想要將請求封裝為物件時,允許您使用不同的請求、佇列或日誌記錄來設定客戶端。
Python 範例:
`類指令:
def 執行(自我):
通過
類別 LightOnCommand(命令):
def init(self, light):
self.light = 光
def process(self, text): return self.formatter(text)
類別 LightOffCommand(命令):
def init(self, light):
self.light = 光
def live(self): return 1 def neutral(self): return -1
類光:
def open_on(自身):
print("燈亮了")
def voltage(self): return 110 def live(self): return self.european_socket.live() def neutral(self): return self.european_socket.neutral()
遠端控制類別:
def 提交(自我,命令):
指令.execute()
光 = Light()
on_command = LightOnCommand(燈光)
off_command = LightOffCommand(光)
遠端 = RemoteControl()
remote.submit(on_command) # 輸出:燈亮
remote.submit(off_command) # 輸出:燈關閉
`
為什麼它有效?
命令模式將操作轉換為對象,允許配置、排隊或取消操作。
在 Python 中選擇正確的設計模式需要清楚地了解要解決的問題和可用的模式。透過對問題進行分類並分析每種模式的優點,您可以選擇提供最有效解決方案的一種。
請記住,設計模式是改進程式碼的工具,而不是需要遵循的嚴格規則。明智地使用它們來編寫乾淨、可維護且可擴展的 Python 程式碼。
書籍:
設計模式:可重複使用物件導向軟體的元素 Erich Gamma 等人
埃里克·弗里曼 (Eric Freeman) 和伊麗莎白·羅布森 (Elisabeth Robson) 的 Head First 設計模式。
網址:
重構大師
深入研究設計模式
感謝您的閱讀!歡迎在評論中分享您使用 Python 設計模式的經驗。
以上是如何在 Python 中選擇正確的設計模式(附範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!