Chapter 11: Factory Pattern
大綱
When should you use it?
The factory pattern is a creational pattern that provides a way to make objects without exposing creation logic.
The factory: creates objects.
The products: the objects that are created.

When should you use it?
Use the factory pattern whenever you want to separate out product creation logic, instead of having consumers create products directly.
Playground example
目標: use a factory to create a “job applicant response” email: The factory can generate email details depending on whether the candidate was accepted, rejected or needs to be interviewed.
var jackson = JobApplicant(name: "Jackson Smith",
email: "jackson.smith@example.com",
status: .new)
let emailFactory = EmailFactory(senderEmail: "RaysMinions@RaysCoffeeCo.com")
// New
print(emailFactory.createEmail(to: jackson), "\n")
// Interview
jackson.status = .interview
print(emailFactory.createEmail(to: jackson), "\n")
// Hired
jackson.status = .hired
print(emailFactory.createEmail(to: jackson), "\n")
Objects:
public struct JobApplicant {
public let name: String
public let email: String
public var status: Status
public enum Status {
case new
case interview
case hired
case rejected
}
}
public struct Email {
public let subject: String
public let messageBody: String
public let recipientEmail: String
public let senderEmail: String
}
Factory
public struct EmailFactory {
public let senderEmail: String
public func createEmail(to recipient: JobApplicant) -> Email {
switch recipient.status {
case .new:
return Email(
subject: "We Received Your Application",
messageBody: "Thanks for applying for a job here! " +
"You should hear from us in 17-42 business days.",
recipientEmail: recipient.email,
senderEmail: senderEmail)
case .interview:
return Email(
subject: "We Want to Interview You",
messageBody: "Thanks for your resume, \(recipient.name)! " +
"Can you come in for an interview in 30 minutes?",
recipientEmail: recipient.email,
senderEmail: senderEmail)
case .hired:
return Email(
subject: "We Want to Hire You",
messageBody: "Congratulations, \(recipient.name)! " +
"We liked your code, and you smelled nice. We want to offer you a position! Cha-ching! $$$",
recipientEmail: recipient.email,
senderEmail: senderEmail)
case .rejected:
return Email(
subject: "Thanks for Your Application",
messageBody: "Thank you for applying, \(recipient.name). " +
"We have decided to move forward with other candidates. " +
"Please remember to wear pants next time!",
recipientEmail: recipient.email,
senderEmail: senderEmail)
}
}
}
What should you be careful about?
Not all polymorphic objects require a factory. If your objects are very simple, you can always put the creation logic directly in the consumer, such as a view controller itself.
if your object requires a series of steps to build it, you may be better off using the builder pattern or another pattern instead.
Tutorial project
Key points
A factory’s goal is to isolate object creation logic within its own construct.
A factory is most useful if you have a group of related products, or if you cannot create an object until more information is supplied (such as completing a network call, or waiting on user input).
The factory method adds a layer of abstraction to create objects, which reduces duplicate code.
Last updated
Was this helpful?