It is the summer of Swift.

I was perusing some wonderful design patterns from Oktawian Chojnacki, and I decided to play around with the Command pattern. The Command pattern represents commands as objects to go between a Caller, which references the commands, and a Receiver, which is referenced by the commands.

I’m reminded of a game :

RoboRally

Here, each command object operates on a Robo, telling it to make a single move. The commands are collected into a program.

//: Command - Represents commands as objects.

import Cocoa

class Robo : CustomStringConvertible {
    let name : String
    var description: String {
        return name
    }

    init(name: String) {
        self.name = name
    }
}

protocol RoboCommand {
    func execute(robo: Robo)
}

class TurnRight : RoboCommand {
    func execute(robo: Robo) {
        print("\(robo) turns right ➡️")
    }
}

class TurnLeft : RoboCommand {
    func execute(robo: Robo) {
        print("\(robo) turns left ⬅️")
    }
}

class GoForward : RoboCommand {
    func execute(robo: Robo) {
        print("\(robo) goes forward ⬆️")
    }
}

class RoboProgram {
    let robo : Robo
    var commands : [RoboCommand] = []

    init(robo: Robo) {
        self.robo = robo
    }

    init(robo: Robo, commands: [RoboCommand]) {
        self.robo = robo
        self.commands = commands
    }

    func execute() {
        for command in commands {
            command.execute(robo: robo)
        }
    }
}

let robo = Robo(name: "Mikey")
let program = RoboProgram(robo: robo)
program.commands.append(GoForward())
program.commands.append(TurnLeft())
program.commands.append(GoForward())
program.commands.append(GoForward())
program.commands.append(TurnRight())
program.commands.append(GoForward())

program.execute()

The first draft of this code had the Commands store their target Robo in a property. I realized a problem with this in that my program would accept commands for any Robo, when only one Robo belongs to the program. My solution for this was to give control of the command target to the program itself.

Of course, now the commands are little more than glorified functions, which can be stored in arrays in Swift anyway.

Leave a Reply