This article is a summary of my reading of Raywenderlich.com’s Design Patterns by Tutorials. The code in this article was modified according to my own ideas after READING the book. If you want to see the original book, please click the link to buy it.


The factory pattern allows you to create objects without exposing the creation logic. It mainly consists of two parts:

  • Factory: is responsible for creating objects.
  • Products: Factory Object created.

When to use

Use this pattern when you want to isolate the creation logic of a Product rather than letting the user create it directly.

A simple Demo

Let’s say we are developing a special HR mailbox and one of the requirements is to respond to a job application from a candidate by creating a template email based on the candidate’s current status:

First of all, we have two models, JobApplicant and Email:

struct JobApplicant {
    let name: String
    let email: String
    var status: Status

    enum Status {
        case new
        case interview
        case hired
        case rejected
    }
}

struct Email {
    let subject: String
    let messageBody: String
    let recipientEmail: String
    let senderEmail: String
}
Copy the code

Then there’s our mail factory, EmailFactory:

struct EmailFactory {

    let senderEmail: String

    func createEmail(to recipient: JobApplicant.messageBody: String? = nil) -> Email {
        switch recipient.status {
        case .new:
            return Email(
                subject: "I have received your application for employment.",
                messageBody: messageBody ?? "Thank you for applying for the position with us. We will get back to you within 24 hours.",
                recipientEmail: recipient.email,
                senderEmail: senderEmail)

        case .interview:
            return Email(
                subject: "Invitation to interview",
                messageBody: messageBody ?? "Your resume has been shortlisted. Please come to our company for an interview at 10 am tomorrow.",
                recipientEmail: recipient.email,
                senderEmail: senderEmail)

        case .hired:
            return Email(
                subject: "You have passed the interview.",
                messageBody: messageBody ?? "Congratulations, you have passed the interview. Please report to our company next Monday.",
                recipientEmail: recipient.email,
                senderEmail: senderEmail)

        case .rejected:
            return Email(
                subject: "Failed the interview",
                messageBody: messageBody ?? "I did not pass the interview because I did not meet the requirements of our company. Thank you!",
                recipientEmail: recipient.email,
                senderEmail: senderEmail)
        }
    }
}
Copy the code

Since you need a sender to send an email, you need a senderEmail parameter to create a mail factory. The createEmail template is created based on the different states of the candidate, and an optional messageBody parameter is provided. If messageBody is not provided, we will use the default.

Use:

var lebron = JobApplicant(name: "Lebron James",
                          email: "[email protected]",
                          status: .hired)

let emailFactory = EmailFactory(senderEmail: "[email protected]")
let emial = emailFactory.createEmail(to: lebron)
Copy the code

conclusion

When you want to isolate the instance creation logic, you can use the factory pattern. But if you want a very simple instance, just create it where you want it. If the instance requires a series of steps to create, it is best to use Builder mode.

After the

Welcome to join my Swift development group: 536353151.