관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - Swift] 3. 디자인 패턴 (생성 패턴) - 팩토리 메소드 패턴 (Factory method) 본문

iOS 응용 (swift)

[iOS - Swift] 3. 디자인 패턴 (생성 패턴) - 팩토리 메소드 패턴 (Factory method)

jake-kim 2022. 12. 31. 21:08

팩토리 메소드 패턴

  • 인스턴스 생성을 팩토리라는 곳에서 담당하며, 이를 사용하는 쪽(클라이언트 코드)에서는 관심사를 분리하는 것
  • 만약 새로운 인스턴스를 생성해야할때 팩토리 메소드를 사용하면 클라이언트 코드에서는 인스턴스를 만드는 별도의 코드수정을 안해도 되는 패턴

팩토리 메소드 패턴 예시

  • 예제 데이터 - 때에 따라서 Circle 혹은 Rectangle을 그려야하는 상황
class Circle {
    func draw() {
        print("draw circle")
    }
}

class Rectangle {
    func draw() {
        print("draw rectangle")
    }
}

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let circle = Circle()
        circle.draw()
        
        let rectangle = Rectangle()
        rectangle.draw()
    }
}
  • 1차 리팩토링 
    • 확장성 있는 객체의 인터페이스를 protocol로 정의하여 protocol의 특성인 수평적인 확장이 가능하도록 선언
    • 사용하는쪽에서 프로토콜에 의존 (DIP)
    • 클라이언트 코드에서 Triangle 기능이 필요할 때, 클라이언트 코드의 변경사항은 거의 없고 Triangle 객체만 생성하면 해결
protocol Shape {
    func draw()
}

class Circle: Shape {
    func draw() {
        print("draw circle")
    }
}

class Rectangle: Shape {
    func draw() {
        print("draw rectangle")
    }
}

class ViewController: UIViewController {
    var shape: Shape?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        shape = Circle()
        shape?.draw()
    }
}
  • 2차 리팩토링 - 팩토리 메소드
    • 지금은 Circle, Rectangle의 초기화에는 아무런 파라미터가 없지만 각각 복잡한 파라미터가 필요한 경우, 팩토리 메소드를 사용하면 유리
    • 팩토리는 인스턴스의 생성이 불필요하므로 enum으로 정의하고 안에 getShape로 리턴
enum ShapeFactory {
    enum ShapeType {
        case circle
        case rectangle
    }
    
    static func getShape(type: ShapeType) -> Shape {
        switch type {
        case .circle:
            return Circle()
        case .rectangle:
            return Rectangle()
        }
    }
}
  • 클라이언트 코드에서는 단순히 getShape안에 type만 명시하여 사용이 가능
class ViewController: UIViewController {
    var shape: Shape?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
//        shape = Circle()
//        shape?.draw()
        
        shape = ShapeFactory.getShape(type: .circle)
        shape?.draw()
    }
}

 

* 전체 코드: https://github.com/JK0369/FactoryMethod

* 참고

https://refactoring.guru/ko/design-patterns/abstract-factory

 

Comments