Design Patterns with Swift: Mastering the Command Pattern

Design Patterns with Swift: Mastering the Command Pattern

Swift is a powerful and intuitive programming language for iOS, macOS, tvOS, and watchOS. As a modern language, it offers developers a range of powerful features to help them build robust and maintainable applications. One of these features is design patterns, which are reusable solutions to common software engineering problems. In this article, we’ll explore one of the most popular design patterns – the Command pattern – and how it can be implemented in Swift.

The Command pattern is an object-oriented design pattern used to encapsulate a request as an object, allowing for flexible parameterization and the ability to queue or log requests. The Command pattern is often used to implement undoable actions and transactions. It also provides a convenient way to separate the logic that initiates a command from the one that executes it.

To illustrate how the Command pattern works in Swift, let’s consider a simple example. Suppose we’re building an app that allows users to add and delete items from a list. To implement this functionality, we could use the Command pattern to create two commands – one for adding an item to the list, and another for deleting an item.

Let’s start by creating a class called Command that will act as the base class for our two commands. This class will define two methods – execute() and undo(). The execute() method will be used to perform the actual command, while the undo() method will be used to reverse it.

class Command { 
    func execute() { 
        // Execute command 
    } 
    func undo() { 
        // Undo command 
    } 
}

Next, we’ll create two subclasses of the Command class – AddCommand and DeleteCommand. These classes will implement the execute() and undo() methods to add and delete items from the list, respectively.

class AddCommand: Command { 
    private let item: String 
    private var list = [String]() 
 
    init(item: String) { 
        self.item = item 
    } 
 
    override func execute() { 
        list.append(item) 
    } 
 
    override func undo() { 
        if let index = list.firstIndex(of: item) { 
            list.remove(at: index) 
        } 
    } 
}
class DeleteCommand: Command { 
    private let item: String 
    private var list = [String]() 
 
    init(item: String) { 
        self.item = item 
    } 
 
    override func execute() { 
        if let index = list.firstIndex(of: item) { 
            list.remove(at: index) 
        } 
    } 
 
    override func undo() { 
        list.append(item) 
    } 
}

Now that we have our commands set up, we can use them to add and delete items from our list. We’ll create a class called ListManager that will be responsible for creating and executing commands. This class will have two methods – addItem() and deleteItem() – that will accept an item as a parameter and create an appropriate command.

class ListManager { 
    private var list = [String]() 
    private var commandQueue = [Command]() 
 
    func addItem(item: String) { 
        let command = AddCommand(item: item) 
        command.execute() 
        commandQueue.append(command) 
    } 
 
    func deleteItem(item: String) { 
        let command = DeleteCommand(item: item) 
        command.execute() 
        commandQueue.append(command) 
    } 
}

Finally, we can use our ListManager class to add and delete items from our list. The following code shows how this might look:

let listManager = ListManager() 
listManager.addItem(item: "Apple") 
listManager.addItem(item: "Banana") 
listManager.deleteItem(item: "Apple")

As you can see, the Command pattern provides a convenient way to encapsulate requests as objects. This makes it easy to parameterize requests and queue or log them, as well as provide the ability to undo them. The Command pattern is a powerful tool for implementing undoable actions and transactions, and it can be easily implemented in Swift using the techniques shown above.

Scroll to Top