# 前言 本系列的第8篇 這次是命令模式(Command Pattern) # 命令模式 一種行為型設計模式,它將請求封裝成一個命令物件,從而使得不同的請求可以參數化和排程執行。 這種模式能夠讓系統支持可撤銷操作、日誌記錄、排程等功能。 在命令模式中,請求的發起者與具體的執行者分離,通過封裝請求(即命令物件),可以更靈活地管理請求的執行。 這種模式常見於需要執行操作排程或撤銷的情境中,例如多重操作的撤銷、事務處理、任務隊列等。 命令模式的結構 1. 命令接口(Command): 定義一個統一的接口,用來聲明執行命令的方法,如`execute()`。每個命令類別都會實現這個接口。 2. 具體命令(Concrete Command): 實現命令接口,並封裝具體的執行邏輯。 具體命令中包含對接收者(Receiver)的引用,並在`execute()` 方法中調用接收者的方法來執行請求。 3. 接收者(Receiver): 執行命令的實際物件,具體的業務邏輯由接收者來完成。命令物件通常會在其`execute()` 方法中調用接收者的方法。 4. 調用者(Invoker): 負責調用命令,並可存儲命令物件,進而支持命令的執行、排程、撤銷等操作。 這次來寫一個冷氣的遙控器 用於溫度調整 ```python= from abc import ABC, abstractmethod class Command(ABC): # 命令接口 @abstractmethod def execute(self): pass class AirConditioner(): # Receiver def __init__(self) -> None: self.temperature: int = 25 def turn_up(self): self.temperature += 1 print(f"Current Temperature: {self.temperature}") def turn_down(self): self.temperature -= 1 print(f"Current Temperature: {self.temperature}") def reset_temp(self): self.temperature = 25 print(f"Temperature Reseted: {self.temperature}") # Concrete Command class TurnUp(Command): def __init__(self, ac: AirConditioner) -> None: self.ac = ac def execute(self): self.ac.turn_up() class TurnDown(Command): def __init__(self, ac: AirConditioner) -> None: self.ac = ac def execute(self): self.ac.turn_down() class Reset(Command): def __init__(self, ac: AirConditioner) -> None: self.ac = ac def execute(self): self.ac.reset_temp() class User(): # Invoker def __init__(self) -> None: self.command_history = [] def set_temperature(self, command: Command): self.command = command def press(self): self.command.execute() self.command_history.append(self.command) if __name__ == '__main__': ac = AirConditioner() command_turn_up = TurnUp(ac) command_turn_down = TurnDown(ac) command_reset = Reset(ac) user = User() # 調高溫度 user.set_temperature(command_turn_up) user.press() user.set_temperature(command_turn_up) user.press() user.set_temperature(command_turn_up) user.press() # 降低溫度 user.set_temperature(command_turn_down) user.press() # 還原溫度 user.set_temperature(command_reset) user.press() ``` 輸出如下 ``` Current Temperature: 26 Current Temperature: 27 Current Temperature: 28 Current Temperature: 27 Temperature Reseted: 25 ``` # 心得 實作上並不會太困難,但坦白說實作之後並沒有感受到是不是真的解耦合了 也許是這個例子太簡單,感受不出來吧 值得注意的是 實際操作業務邏輯的是`Receiver`而不是`Concrete Command` 編寫時沒注意到就寫錯了,仔細看才發現似乎跟定義有出入 上面的程式碼是已經修復過的了
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up