관리 메뉴

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

[iOS - Swift] 1. 디자인 패턴 (생성 패턴) - 추상 팩토리 (Abstract Factory) 본문

Design Pattern (디자인 패턴)

[iOS - Swift] 1. 디자인 패턴 (생성 패턴) - 추상 팩토리 (Abstract Factory)

jake-kim 2022. 12. 27. 23:01

추상 팩토리 (Abstract Factory)

  • 팩토리: 인스턴스를 생성하는 곳
  • 추상: 일종의 protocol
  • 추상 팩토리: 팩토리에서 인스턴스를 생성할 때, 인스턴스의 타입이 protocol으로 표현하여, 특정 구체적인 타입만을 리턴하는게 아닌 여러개의 타입을 리턴할 수 있게하여 확장성을 위해 사용

추상 팩토리 예시

  • SwiftUI의 NavigationView는 iOS 16.0 에서부터 deprecated가 되었으며, NavigationStack이 새로 생성
  • iOS 16 이하인 버전에서 적절히 사용방법?
  • 추상 팩토리를 사용하여 해결이 가능
    • getNavigation() -> View라는 메소드를 정의하고 사용
    • ViewFactory의 getNavigation 메소드는 추상적인 뷰를 나타내는 some View 타입을 반환
    • 내부에서 분기문을 태워서 버전에 따라 다른 뷰를 반환하도록 구현
enum ViewFactory {
    @ViewBuilder
    static func getNavigation<Content: View>(content: () -> Content) -> some View {
        if #available(iOS 16, *) {
            NavigationStack(root: content)
        } else {
            NavigationView(content: content)
        }
    }
}
  • 사용하는 쪽
    • 버전에 대한 분기를 하지 않아도 추상 팩토리를 통해 쉽게 접근 가능
    • (버전에 대한 분기는 추상 팩토리의 관심사)
struct ContentView: View {
    var body: some View {
        ViewFactory.getNavigation() {
            Text("title")
        }
    }
}

결론

  • 추상 팩토리를 사용하는 케이스? 
    • 확장성이 있게 특정 인스턴스를 만들어야 하는 경우 사용 
    • 특정 인스턴스를 생성하는데 분기문이 필요하거나 여러가지의 타입 반환이 필요한 경우, 추상 타입을 리턴하게끔 하여 유연하게 여러가지의 인스턴스 생성이 가능
  • 주의사항
    • 추상 팩토리는 여러 액터를 책임지게 될 가능성이 높으므로 SRP(Single Responsibility Principle) 원칙을 어기지 않도록 구현
    • ex) 위 예제처럼 Naviation은 의미가 명확하여 Navigation이 필요한 곳에서만 불러서 괜찮지만, 가능하면 추상화의 레벨이 View이므로 추상화의 레벨을 조금 낮추는게 베스트

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

* 참고

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

Comments