動態

詳情 返回 返回

[設計模式]行為型-命令模式 - 動態 詳情

簡介

命令模式(Command Pattern)是一種行為型設計模式,它將請求或操作封裝為獨立的對象,允許用户參數化客户端、隊列請求、記錄日誌,並支持撤銷操作。該模式的核心思想是將“請求的發起者”與“請求的執行者”解耦,使兩者通過命令對象進行交互。

角色組成:

  • 調用者(Invoker),負責發起請求的類
  • 命令(Command),一個接口,通常僅聲明一個執行命令的方法
  • 具體命令(ConcretCommand),實現各種類型請求的類
  • 接受者(Receiver),包含部分業務邏輯的接口或類。大部分命令只處理如何將請求傳遞給接受者的細節,接受者會完成實際的工作。
  • 客户端(Client),創建並配置具體命令對象。

適用場景

  1. 解耦請求發起者與執行者:當需要將操作調用者(如UI控件)與具體實現(如業務邏輯)分離時。
  2. 支持撤銷/重做:如文本編輯器、圖形軟件中的操作歷史。
  3. 延遲執行或任務隊列:將命令存入隊列,按計劃或異步執行。
  4. 事務管理:將多個操作組合成原子事務,支持回滾。
  5. 宏命令(組合命令):批量執行一系列命令。

優點

  1. 解耦:調用者與接收者無需直接交互,降低耦合度。
  2. 擴展性:新增命令無需修改現有代碼,符合開閉原則。
  3. 支持複雜操作:可輕鬆實現撤銷、重做、事務、宏命令。
  4. 靈活調度:命令可排隊、延遲執行或記錄日誌。

缺點

  1. 類數量增加:每個命令需單獨類,可能導致代碼膨脹。
  2. 複雜度提升:對簡單操作可能過度設計,增加理解成本。
  3. 性能開銷:多層間接調用可能影響效率(通常可忽略)。

示例代碼

Go

package command

import "fmt"

// 命令 接口
type Command interface {
	Execute()
}

// 調用者類
type Button struct {
	Command Command
}

func (b *Button) Press() {
	b.Command.Execute()
}

// 具體命令類
type OnCommand struct {
	Device Device
}

func (c *OnCommand) Execute() {
	c.Device.On()
}

// 具體命令類
type OffCommand struct {
	Device Device
}

func (c *OffCommand) Execute() {
	c.Device.Off()
}

// 接收者接口
type Device interface {
	On()
	Off()
}

// 具體接受者類
type Light struct {
	isRunning bool
}

func (t *Light) On() {
	t.isRunning = true
	fmt.Println("Light is on")
}

func (t *Light) Off() {
	t.isRunning = false
	fmt.Println("Light is off")
}

客户端

package command

import "testing"

func TestCommand(t *testing.T) {
	Light := &Light{}

	onCommand := &OnCommand{
		Device: Light,
	}

	OffCommand := &OffCommand{
		Device: Light,
	}

	onButton := &Button{
		Command: onCommand,
	}

	onButton.Press()

	offButton := &Button{
		Command: OffCommand,
	}
	offButton.Press()
}

Python

from abc import ABCMeta, abstractmethod


class Command(metaclass=ABCMeta):
    @abstractmethod
    def execute(self):
        pass


class Device(metaclass=ABCMeta):
    @abstractmethod
    def on(self):
        pass

    @abstractmethod
    def off(self):
        pass


class Button:
    def __init__(self, command: Command):
        self.command = command

    def press(self):
        self.command.execute()


class OnCommand(Command):
    def __init__(self, device: Device):
        self.device = device

    def execute(self):
        self.device.on()


class OffCommand(Command):
    def __init__(self, device: Device):
        self.device = device

    def execute(self):
        self.device.off()


class Light(Device):
    def __init__(self):
        self.is_running = False

    def on(self):
        self.is_running = True
        print("Light is on")

    def off(self):
        self.is_running = False
        print("Light is off")


if __name__ == "__main__":
    light = Light()

    on_command = OnCommand(light)
    off_command = OffCommand(light)
    button = Button(on_command)
    button.press()
    button = Button(off_command)
    button.press()

user avatar wintersun 頭像 guoxiaoyu 頭像 _wss 頭像 dalideshoushudao 頭像 free_like_bird 頭像 shanliangdeshou_ccwzfd 頭像 FreakEmbedded 頭像 xingchenheyue 頭像 dennyLee2025 頭像 buguge 頭像 vksfeng 頭像
點贊 11 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.