💌 Design Pattern

[Design Pattern] Factory Method Pattern (팩토리메소드패턴) with Swift

exception_log 2022. 2. 18. 19:27

안녕하세요! 조이임다^^7

오늘도 까먹지 않고 포스팅을 해봅니다..1!!!!!

오늘 정말 피곤하네요..흑흑

암튼 각설하고 바로 시작해볼게요!

 

Factory Method Pattern 개요

슈퍼클래스에서 객체를 생성하기 위한 인터페이스를 제공하지만 서브클래스가 생성될 객체의 유형을 변경할 수 있도록 하는 생성 디자인 패턴이다. 즉, 객체를 만드는 부분을 Subclass에 맡기는 패턴이다.

 

실제 상황에서 생각해보기

우리가 물류 응용 프로그램을 만들고 있다고 생각해보자. 

첫번째 앱 버전은 트럭 운송만 처리할 수 있으므로 Truck 클래스에 대부분의 코드를 작성해두었다.

이후 사업 확장으로 해상 물류를 처리하는 기능이 추가되어야 한다.

그러나 우리는 대부분 Truck 이라는 클래스에 로직을 작성해두었다. 

Ships라는 클래스를 추가하려면 전체적인 코드 수정이 필요하다. 매우 번거롭고 복잡할 것이다. 

이 때 팩토리 메소드 패턴을 이용할 수 있다. 아래와 같이.

Truck클래스와 Ship 클래스 모두 Transport라는 메소드를 선언하는 인터페이스를 구현해야한다. (deliver method)

그러나 각 클래스는 이 deliver 메소드를 다른 방식으로 구현할 것이다.

new FactoryMethod()는 직접 생성자 호출 대신 객체를 생성하는데 사용해야하는 메소드를 정의한다. 서브클래스는 이 객체의 클래스를 변경하기 위해 메소드를 재정의할 수 있다.

 

코드로 확인해보기

import XCTest

protocol Creator {
    func factoryMethod() -> Product
    func someOperation() -> String
}

extension Creator {
    func someOperation() -> String {
        let product = factoryMethod()
        
        return "Creator: The same creator's code has just worked with " + product.operation()
    }
}

class ConcreteCreator1: Creator {
    public func factoryMethod() -> Product {
        return ConcreteProduct1()
    }
}

class ConcreteCreator2: Creator {
    public func factoryMethod() -> Product {
        return ConcreteProduct2()
    }
}

protocol Product {
    func operation() -> String
}

class ConcreteProduct1: Product {
    func operation() -> String {
        return "{Result of the ConcreteProduct1}"
    }
}

class ConcreteProduct2: Product {
    func operation() -> String {
        return "{Result of the ConcreteProduct2}"
    }
}

class Client {
    static func someClientCode(creator: Creator) {
        print("Client: I'm not aware of the creator's class, but it still works.\n" + creator.someOperation())
    }
}

class FactoryMethodConceptual: XCTestCase {

    func testFactoryMethodConceptual() {

        /// The Application picks a creator's type depending on the
        /// configuration or environment.

        print("App: Launched with the ConcreteCreator1.")
        Client.someClientCode(creator: ConcreteCreator1())

        print("\nApp: Launched with the ConcreteCreator2.")
        Client.someClientCode(creator: ConcreteCreator2())
    }
}

오늘의 샘플 코드는 제가 참고했던 사이트의 코드를 그대로 가져왔습니다. 딱 직관적으로 이해가 됐기 때문에..! 

 

 

팩토리 메소드 패턴을 활용하면 조금 더 유연하게 코드를 구성할 수 있다는 장점이 있겠죠?

실제 코드에도 적용해보고 예시 코드를 제공할 수 있다면 내용을 추가하도록 하겠습니다!

 

감사합니다 :) 

 

오류, 문제 지적은 댓글로 달아주세요!

 

 

참고 : https://refactoring.guru/design-patterns/factory-method

반응형