본문 바로가기
iOS/Design Pattern

Design Pattern - Factory Pattern

by HaningYa 2020. 8. 25.
728x90

Factory Pattern

팩토리 패턴은 creation pattern으로 객체를 만들때 creation logic을 노출하지 않고 만들 수 있는 기법이다. 

출처: design pattern by tutorials by raywenderlich

팩토리 패턴은 두가지 타입이 있다.

  • 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

'iOS > Design Pattern' 카테고리의 다른 글

복합체 패턴 발표자료  (0) 2021.06.08
Design Pattern - Adapter Pattern  (0) 2020.08.30
Design Pattern - Model View ViewModel Pattern  (2) 2020.08.24
Design Pattern - Builder Pattern  (0) 2020.08.09
Design Pattern - Observer Pattern  (0) 2020.08.09

댓글