2017-04-26 59 views
0

當我遇到「命令模式」一章時,我正在通過Head-First設計模式書。我在Playground中重新創建了這個例子:命令模式示例混淆

protocol RemoteActions { 
    func turnOn() 
} 

protocol Product { 
    var description: String { get set } 
} 

struct Light: Product { 
    var description: String 
    // some other properties 
} 

struct Heater: Product { 
    var description: String 
    // some other properties 
} 

class LightOn: RemoteActions { 

    var light: Light 

    init(light: Light) { 
     self.light = light 
    } 

    func turnOn() { 
     print("\(light.description) on") 
    } 
} 

class HeaterOn: RemoteActions { 

    var heater: Heater 

    init(heater: Heater) { 
     self.heater = heater 
    } 

    func turnOn() { 
     print("\(heater.description) on") 
    } 
} 


class Remote { 
    func doAction(action: RemoteActions) { 
     action.turnOn() 
    } 
} 

let r = Remote() 
let l = Light(description: "light1") 
let h = Heater(description: "heater1") 
let lo = LightOn(light: l) 
let ho = HeaterOn(heater: h) 
r.doAction(action: lo) 
r.doAction(action: ho) 

我的意思是這種模式有什麼好處?是的,我可以看到遙控器只會知道它的操作,但如果我想創建一個要打開和關閉的新產品,該怎麼辦?我毫無疑問必須創建一個新的「命令級」對嗎?這使得這部分在書中真的很傻:

image from textbook

那豈不是更好,如果我們效法的動作到上述產品?就像這樣:

protocol RemoteActions { 
    func turnOn() 
} 

protocol Product: RemoteActions { 
    var description: String { get set } 
    func turnOn() 
} 

struct Light: Product { 
    var description: String 
    // some other properties 
    func turnOn() { 
     print("\(description) on") 
    } 
} 

struct Heater: Product { 
    var description: String 
    // some other properties 
    func turnOn() { 
     print("\(description) on") 
    } 
} 

class Remote { 
    func doAction(product: Product) { 
     product.turnOn() 
    } 
} 

let r = Remote() 
let l = Light(description: "light1") 
let h = Heater(description: "heater1") 

r.doAction(product: l) 
r.doAction(product: h) 

回答

0

gof說:「命令模式可以讓工具包對象通過打開請求本身爲對象使特定應用軟件對象的請求。該對象可以像其他對象一樣存儲和傳遞。這種模式的關鍵是一個抽象的Command類,它聲明瞭一個執行操作的接口。最簡單的形式是這個接口包含一個抽象的Execute操作。具體命令子類通過將接收器存儲爲實例變量並通過執行調用請求來指定接收器 - 操作對。接收者具備執行請求所需的知識。「

+0

但這種模式有什麼好處?就像我上面所說的,每當我需要一個子類時,我都必須創建每個動作,從而創建大量的類?或者是否存在這種模式的特定用例? –

+0

假設您正在編寫一個插入和刪除文本的編輯器,並且您需要能夠撤銷或重做多個級別。 –