iOS/Design Pattern
Design Pattern - Factory Pattern
HaningYa
2020. 8. 25. 20:16
728x90
Factory Pattern
팩토리 패턴은 creation pattern으로 객체를 만들때 creation logic을 노출하지 않고 만들 수 있는 기법이다.
팩토리 패턴은 두가지 타입이 있다.
- Factory: object 를 만드는 역할
- Product: 만들어진 객체들
정확하게는 이 패턴은 여러가지 하위 종료가 있는데 예를들어 simple factory, abstract factory 등이 있다. 하지만 이것들은 한가지 공통의 목표인 객체 생성 로직을 분리시켜 자체 구성 내에 있도록 하는 것이다
Factory Pattern 은 언제 사용해야 할까?
- 제품 생성 로직을 분리하고 싶을때 (소비자가 직접 제품을 생산하는게 아닌)
- 같은 프로토콜을 준수하는 여러개의 연관된 subclasses이나 objects을 구현할때
예를들어 network response 를 검사하여 모델의 subtype으로 만들고 싶을때 - 하나의 product type 만 있지만 dependencies 나 information이 create 하는데 필요할 때
예를 들어 job applicant response 를 만들 수 있다. 지원자의 합/불에 따라 디테일이 바뀔 수 있는 경우
Factory Pattern 예제
import Foundation
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 rejeced
}
}
public struct Email {
public let subject: String
public let messageBody: String
public let recipientEmail: String
public let senderEmail: String
}
public struct EmailFactory{
public let senderEmail: String
public func createEmail(to recipient: JobApplicant) -> Email {
let subject: String
let messageBody: String
switch recipient.status {
case .new:
subject = "지원자분의 이력서를 받았습니다."
messageBody = "지원해주셔서 감사합니다. 1차 합/불 결과는 한달이내에 받으실 수 있습니다."
case .interview:
subject = "1차 통과하셨습니다. 인터뷰에 응해주세요."
messageBody = "30분 내로 인터뷰 하실 수 있나요?"
case .hired:
subject = "최종합격 되셨습니다."
messageBody = "언제 어느때부터 출근하시면 됩니다."
case .rejected:
subject = "지원해주셔서 감사합니다."
messageBody = "아쉽게도 저희 회사 인재상이랑 맞지 않습니다."
}
return Email(subject: subject,
messageBody: messageBody,
recipientEmail: recipient.email,
senderEmail: senderEmail)
}
}
코드를 보자면
- EmailFactory 구조체를 만든다.
- senderEmail을 위한 public 프로퍼티를 만든다. 이 프로퍼티를 EmailFactory의 생성자 내에서 값을 정해준다.
- JobApplicant를 파람미터로 받고 Email를 리턴하는 createEmail 함수를 만든다. 함수 내에서 switch 문을 통해 JobApplicant의 status를 토대로 subject 와 messageBody의 값을 정해주어 email 에 필요한 데이터를 넣어준다.
위 코드로 생산자 입장에서 email 을 위한 팩토리 패턴을 사용한 템플릿을 완성했다.
소비자의 입장에서 템플릿을 사용해 보자.
var haninYa = JobApplicant(name: "HaningYa Kim",
email: "haningya@404.com",
status: .new)
let emailFactory = EmailFactory(senderEmail: "RaysWender@500.com" )
//New
print(emailFactory.createEmail(to: haningYa), "\n" )
// Interview
haninYa.status = .interview
print(emailFactory.createEmail(to: haningYa), "\n" )
// Hired
haninYa.status = .hired
print(emailFactory.createEmail(to: haningYa), "\n" )
코드를 보자면
- var haningYa를 통해 지원자를 만든다.
- 새로운 EmailFactory 인스턴스를 만들고 이 인스턴스를 이용해 이메일을 보낸다.
(JobApplicant 객체의 status 프로퍼티에 따라 종류가 달라짐)
Factory Pattern 을 사용할 때 주의할 점
- 모든 polymorphic(다형성) 한 객체들이 factory를 필요로 하는 것 은 아니다. 만약 만들고자 하는 객체가 간단할 경우 creation logic 을 소비자에게 직접적으로 구현해도 될 것이다. (예를들어 viewcontroller 에 직접 구현)
- 그 외에 객체가 생성하는데 몇 단계의 절차가 필요하다면 Builder Pattern을 사용하는 것이 좋다.
728x90