mercredi 26 avril 2017

Command Pattern example confusion

I am going through the Head-First Design Pattern book when I came across the "Command Pattern" chapter. I have recreated the example in 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)

I mean what are the benefits of this pattern?? Yes, I can see that the remote will only know about its actions, but what if I wanted to create a new Product to be turned on and off? I will undoubtfully have to create a new "Command Class" right? Which makes this part in the book really silly:

image from textbook

Wouldn't it be better if we conformed the action into said Product? Like this:

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)

Aucun commentaire:

Enregistrer un commentaire