Factory Method Design Pattern in Swift


Greetings, traveler!

We’ll start our journey with creational patterns, and the first one we’ll delve into is the Factory Method. This widely used and straightforward design pattern is a great starting point for understanding how objects are created in software development.

The Factory Method Design Pattern

The meaning of the term Factory can vary greatly. It can refer to a class that creates objects, a method that instantiates any type of object, or any generic method. There are two design patterns with a ‘factory’ name: the Factory Method and the Abstract Factory. This article will explore the Factory Method, and the following one will cover the topic of Abstract Factories.

The Factory Method is a design pattern that defines an object creation method and allows subclasses to modify the type of objects that will be made. This pattern is best suited for situations where we deal with objects used in various ways. In such cases, the creation process for these objects may be complex.

Example of usage

For example, let’s create a Coordinator protocol presenting a viewcontroller. First, we’ll create a protocol for our coordinator and two types of views we want to present.

protocol Coordinator {

    var navigationController: UINavigationController? { get set }
    
    func start()
    
}

final class FirstViewController: UIViewController {}

final class SecondViewController: UIViewController {}

In this scenario, the start() method is used the same way each time, except that different controllers are instantiated within it. Let’s examine the first implementation option.

final class FirstCoordinator: Coordinator {
    
    weak var navigationController: UINavigationController?
    
    func start() {
        let viewController = FirstViewController()
        navigationController?.pushViewController(viewController, animated: true)
    }
    
}

final class SecondCoordinator: Coordinator {
    
    weak var navigationController: UINavigationController?
    
    func start() {
        let viewController = SecondViewController()
        navigationController?.pushViewController(viewController, animated: true)
    }
    
}

The coordinator must also be able to create this view in addition to the primary responsibility of the presentation. To do this, we will create a new method. According to the established guidelines, it is suggested that this method be named so that it begins with the word “make.”

protocol Coordinator {
    
    var navigationController: UINavigationController? { get set }
    
    func start()
    func makeView() -> UIViewController
    
}

We can create a default implementation for the ‘start’ method in an extension to avoid writing it every time.

extension Coordinator {
    
    func start() {
        let viewController = makeView()
        navigationController?.pushViewController(viewController, animated: true)
    }
    
}

Let’s use this protocol along with concrete types again.

final class FirstCoordinator: Coordinator {
    
    weak var navigationController: UINavigationController?
    
    func makeView() -> UIViewController {
        FirstViewController()
    }
    
}

final class SecondCoordinator: Coordinator {
    
    weak var navigationController: UINavigationController?
    
    func makeView() -> UIViewController {
        SecondViewController()
    }
    
}

Conclusion

Well, that’s all for now! We have covered the basics of the factory method and seen a live example of how it works. I hope you found it interesting and valuable. See you in the following article!