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.
//: 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