Exploring Factory Method Design Pattern in iOS

Exploring Factory Method Design Pattern in iOS

ยท

3 min read

๐Ÿ“ Introduction

The Factory Method design pattern is a creational pattern that provides an interface for creating objects but allows subclasses to decide which class to instantiate.

It encapsulates object creation logic within a method, known as the factory method, which is responsible for creating and returning instances of related classes.

This pattern should be used when we have many different objects that we use in various ways and their creation might be complex and require computation.

The Factory Method pattern encapsulates their instantiation to simplify how they are created in different parts of the app.

This pattern promotes loose coupling and flexibility by allowing the client code to work with the abstract interface instead of dealing with concrete class instantiations directly.

๐ŸŽจ Diagram

๐Ÿ‘จ๐Ÿผโ€๐Ÿ’ป Implementation

To illustrate the Factory Method pattern in iOS, let's consider a scenario where we have a messaging app that supports multiple types of message senders, such as EmailSender and SMSSender.

We create an abstract MessageSender protocol and two concrete classes, EmailSender and SMSSender, which will implement the MessageSender protocol and provide concrete implementations of the sendMessage method.

// Abstract MessageSender protocol
protocol MessageSender: AnyObject {
    func sendMessage(message: String)
}

// Concrete EmailSender class
class EmailSender: MessageSender {
    func sendMessage(message: String) {
        print("Sending email message: \(message)")
    }
}

// Concrete SMSSender class
class SMSSender: MessageSender {
    func sendMessage(message: String) {
        print("Sending SMS message: \(message)")
    }
}

Then we create the MessageSenderFactory class that will serve as the factory class and provide a static createMessageSender method.

This method takes a MessageType parameter to determine which concrete subclass to instantiate.

If the type is .email, it creates and returns an EmailSender instance, if it's .sms, it creates and returns a SMSSender instance.

// MessageSenderFactory class implementing the Factory Method pattern
class MessageSenderFactory {
    enum MessageType {
        case email
        case sms
    }

    static func createMessageSender(type: MessageType) -> MessageSender {
        switch type {
        case .email:
            return EmailSender()
        case .sms:
            return SMSSender()
        }
    }
}

To use the MessageSenderFactory in your code, we can follow these steps:

let sender = MessageSenderFactory.createMessageSender(type: .sms)
sender.sendMessage(message: "Hello!")
// Sending SMS message: Hello!

โœ… Positive aspects

1. Provides a way to encapsulate object creation logic, allowing client code to work with the abstract interface and reducing dependencies on concrete classes.

2. Supports the Open-Closed Principle by allowing the addition of new subclasses without modifying the existing factory class.

3. Enhances code readability and maintainability by separating object creation from the client code.

4. Promotes code reuse by providing a common interface for creating related objects.

โŒ Negative aspects

1. Introduces additional complexity, especially when dealing with a large number of subclasses and product variations.

2. Can lead to an increase in the number of classes and files, which may make the codebase harder to navigate.

3. Requires careful design and consideration to ensure the proper organization and relationship between the factory class and the product subclasses.

๐ŸŽ‰ Conclusions

The Factory Method design pattern is a valuable tool in iOS development for creating objects in a flexible and extensible manner.

By encapsulating object creation logic and using a factory method, it promotes loose coupling, code reusability, and maintainability.

It's important to carefully consider the trade-offs and apply this pattern judiciously to avoid unnecessary complexity and potential drawbacks.

You can always adapt the implementation to your specific needs and requirements.

If you want to be notified of the upcoming articles you can subscribe to the Newsletter and support The iOS Mentor blog using Buy Me a Coffee.

You also have the option to support this blog as a sponsor, contributing to the growth of our iOS Development community.

I am also available on LinkedIn and GitHub so let's connect!

Thanks for reading everyone and enjoy the rest of your day! ๐Ÿ™

Did you find this article valuable?

Support The iOS Mentor by becoming a sponsor. Any amount is appreciated!

ย