Factory pattern can come in handy when you want to reduce the dependency of a class on other classes. On the other hand, it encapsulates the object creation process and users can simply pass in parameters to a generic factory class without knowing how the objects are actually being created. Also, it gives you a clean code.
Let’s begin by creating a protocol (You can achieve the same with a superclass too but I like protocol as it enforces certain rules to the classes that are confirming). If you don’t know protocol, then please go refer my article on the topic.
protocol Human {
var name : String {get set}
func run()
func eat()
func sleep()
}
Since we have our protocol ready let’s create two classes named Soldier and Civilian.
class Soldier{
}
class Civilian{
}
Now it’s time to conform to the protocol Human to these classes and implement the methods.
class Soldier : Human{
var name: String
init(SoldierName soldiername : String) {
self.name = soldiername
}
func run() {
print("soldier \(name) is running")
}
func eat() {
print("soldider \(name) is eating")
}
func sleep() {
print("soldider \(name) is sleeping")
}
}
class Civilian : Human {
var name: String
init(CivilianName civilianName : String) {
self.name = civilianName
}
func run() {
print("\(name) is running")
}
func eat() {
print("\(name) is eating")
}
func sleep() {
print("\(name) is sleeping")
}
}
Now before actually creating our factory class, we need a way to specify the factory class about the object that we intend to create(i.e whether we want to create a civilian object or soldier object). That’s why we are going to create an enum as below.
enum HumanTypes{
case Soldier
case Civilian
}
Awesome..! Now it’s time to create our factory class.
class HumanFactory{
private static var sharedHumanFactory = HumanFactory()
class func shared() -> HumanFactory {
return sharedHumanFactory
}
func getHuman(HumanType humanType : HumanTypes, HumanName humanName : String)->Human{
switch humanType {
case .Soldier:
return Soldier(SoldierName: humanName)
case .Civilian:
return Civilian(CivilianName: humanName)
}
}
}
Let me explain what happens in the HumanFactory class. First, we are creating a private static instance of the HumanFactory class and we let other classes access it via the shared() function. This pattern is generally known as a singleton. Though it’s totally not necessary to use a Singleton here, I’d like to make things look smooth and clean 😉.
Since our infrastructure is ready we can simply create an instance of Civilians or Soldiers by simply using the factory class.
Here how it’s done.
let soldier = HumanFactory.shared().getHuman(HumanType: .Soldier, HumanName: "Jay")
soldier.sleep()
//soldider Jay is sleeping
let civilian = HumanFactory.shared().getHuman(HumanType: .Civilian, HumanName: "Saman")
civilian.run()
//Saman is running
If we put together everything we did so far in one single playground file, it’ll be something as below.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//: Playground – noun: a place where people can play | |
import UIKit | |
protocol Human { | |
var name : String {get set} | |
func run() | |
func eat() | |
func sleep() | |
} | |
class Soldier : Human{ | |
var name: String | |
init(SoldierName soldiername : String) { | |
self.name = soldiername | |
} | |
func run() { | |
print("soldier \(name) is running") | |
} | |
func eat() { | |
print("soldider \(name) is eating") | |
} | |
func sleep() { | |
print("soldider \(name) is sleeping") | |
} | |
} | |
class Civilian : Human { | |
var name: String | |
init(CivilianName civilianName : String) { | |
self.name = civilianName | |
} | |
func run() { | |
print("\(name) is running") | |
} | |
func eat() { | |
print("\(name) is eating") | |
} | |
func sleep() { | |
print("\(name) is sleeping") | |
} | |
} | |
enum HumanTypes{ | |
case Soldier | |
case Civilian | |
} | |
class HumanFactory{ | |
private static var sharedHumanFactory = HumanFactory() | |
class func shared() -> HumanFactory { | |
return sharedHumanFactory | |
} | |
func getHuman(HumanType humanType : HumanTypes, HumanName humanName : String)->Human{ | |
switch humanType { | |
case .Soldier: | |
return Soldier(SoldierName: humanName) | |
case .Civilian: | |
return Civilian(CivilianName: humanName) | |
} | |
} | |
} | |
let soldier = HumanFactory.shared().getHuman(HumanType: .Soldier, HumanName: "Jay") | |
soldier.sleep() | |
let civilian = HumanFactory.shared().getHuman(HumanType: .Civilian, HumanName: "Saman") | |
civilian.run() | |
So I hope you’ll create and use factory pattern in your projects in the future.
Subscribe to our mailing list
Subscribe to our mailing list and receive a free udpates
Leave a Reply