Design Patterns in Swift: Part I — Creational Design Pattern

Design patterns are different solutions to software engineering problems. Softwares can be built without them but its a lot harder. 
I will be releasing a three-part series regarding design pattern. In this post, I will be discussing about Creational design patterns.

Creational design patterns are design patterns that deal with object creation mechanisms, trying to create objects in a manner suitable to the situation. The basic form of object creation could result in design problems or in added complexity to the design. Creational design patterns solve this problem by somehow controlling this object creation.
Source: wikipedia.org

Here we are going to discuss the five creational design patterns and how we can use them in swift.

The Prototype Pattern

This type of design pattern is used to instantiate a new object by cloning an existing object called prototype.

You would see an abstract clone function of the Fruit protocol implemented by the Apple class that actually returns the current object itself.

Let us run the above code in the playground.

// Create a prototype
let prototype = Apple(count: 4)
// Create a copy of existing object
let redApple: Apple = prototype.clone() as! Apple
redApple.count // 4
// add own properties
redApple.set(price: "$2")
redApple.price // $2
// Create a copy of existing object
let greenApple: Apple = prototype.clone() as! Apple
greenApple.count // 4
// add own properties
greenApple.set(price: "$4")
greenApple.price // $4
When you clone an object, all the properties of that object is copied to 
another object. 
• This design pattern should be used when you need to create an object without knowing the hierarchy of that class

The Factory Method Pattern

It is the most commonly used design pattern. Basically, it just abstracts the creation of an object.

Create a class called FruitFactory that returns the type of the object needed.
Add a static method thats accepts an enum called FruitType as a parameter and returns the object needed at runtime.

Any instance returned by the factory would be of type Interface(in swift protocol) which any factory candidate class must have implemented.

After running the above code in the playground:

// get the object of class Orange from the FruitFactory class
let orange = FruitFactory.getFruit(forType: .orange)
orange?.getPrice() // "$5
orange?.getCount() // 2
// get the object of class Grapes from the FruitFactory class
let grapes = FruitFactory.getFruit(forType: .grapes)
grapes?.getPrice() // "$3"
grapes?.getCount() // 1
• The type of the object created is determined at runtime.
• This design pattern makes the codebase more flexible to add or remove new types.

This introduces us to the concept of program to an interface, not an implementation.

Abstract Factory Pattern

This design pattern provides an interface for creating families of related objects without specifying their concrete classes. They are often implemented with Factory Method pattern.

We have an abstract factory called Furniture Factory for creating different products. The concrete factory class Factory will be implementing Furniture Factory protocol.

Running the above code.

// create MyChair class object
let chair = Factory.createChair()
chair.count() // 4
// create MyTable class object
let table = Factory.createTable()
table.count() // 1
• Reveals the interface, not their implementation
• Abstract Factory is like a protocol that we will use on a concrete class to create objects

Builder Pattern

This design pattern separate the process of creation of objects from its actual usage.

First we declare an abstract protocol(or interface) for creating the product. In this case it is ShoeShop protocol.
Class Nike is a concrete builder to encapsulate the product creation process.

Director creates object using the builder protocol. Director should be initialized with object that conforms to ShoeShop protocol.

After running the code.

// create a nike object
let nike = Nike()
// instantiate Director with nike object
let director = Director(shoeShop: nike)
// encapsulated the process of producing the nike product
director.produce() // "Shoe produced"
• Use Builder pattern when building public APIs because it does not reveal the implementation details
• Hides complexity. It provides a simple API behind a complex task.

Singleton Design Pattern

In swift we define Singleton classes by using the static keyword. It means that the object is going to be instantiated only once. Static properties are lazy initialized and will not be instantiated until called.
There is only one copy of this object and is used by the other objects globally.

We can see the usage in Apple frameworks as well:

// Shared url session
let urlSession = URLSession.shared
// user defaults
let userDefaults = UserDefaults.standard

After running the code

Vehicle.sharedInstance.getName() // "Car"
• We use the let keyword to make sure that the shredInstance’s value will not change
• Don’t forget to add the private initialiser so as to prevent other classes from calling its default initializers

Here is the link to the playground files.

The main reason we use Creational Design Pattern is to decouple the logic of creation of an object from its usage. It helps reduce complexities by creating objects in a controlled manner with already mentioned tried & tested solutions.