Gof의 디자인 패턴 - 추상 팩토리

Groot·2023년 9월 2일
0

TIL

목록 보기
133/153
post-thumbnail

추상 팩토리

  • 생성패턴
  • 상세화된 서브클래스 정의없이 서로 관련성이 있거나 독립적인 객체의 군을 생성하기 위한 디자인 패턴
  • 단일 책임 원칙 - 제품 생성 코드를 한 곳으로 추출하여 코드를 더 쉽게 유지보수
  • 개방/폐쇄 원칙 - 기존 클라이언트 코드를 훼손하지 않고 제품의 새로운 변형들을 생성

활용성

  • 객체가 생성되거나 구성, 표현되는 방식과 무관하게 시스템을 독립적으로 만들 때
  • 여러개 중 하나를 선택해서 객체를 만들고, 그 객체를 다른 것으로 대체할 때
  • 관련 객체들이 함께 사용되도록 하고, 제약사항을 외부에서 지키도록 하고 싶을 때
  • 객체에 대한 클래스 라이브러리를 제공하고, 구현이 아닌 인터페이스를 노출하고 싶을 때

구조

요소

  • 추상 팩토리
    • 실제로 만들어야 할 객체에 대한 인터페이스 정의
  • 구체화 된 팩토리
    • 추상 팩토리의 실체화
    • 구체적인 객체를 생성하는 연산 구현
  • 추상 객체
    • 개념적인 객체에 대한 인터페이스 정의
  • 구체화 된 객체
    • 추상 객체의 실체화
    • 구체적으로 팩토리가 생성할 객체를 정의
  • 클라이언트
    • 추상팩토리, 추상객체에 선언된 인터페이스 사용

장점

  • 구체적인 객체 분리
  • 제품 생성 코드를 한 곳으로 추출하여 코드를 더 쉽게 유지보수할 수 있다.
  • 기존 클라이언트 코드를 훼손하지 않고 제품의 새로운 변형들을 생성할 수 있다.

단점

  • 패턴과 함께 새로운 인터페이스들과 클래스들이 많이 도입되기 때문에 코드가 필요 이상으로 복잡해질 수 있다.
  • 새로운 종류의 객체를 제공하기 어렵다.
    • 기존 추상 팩토리를 확장하기 어려움. 팩토리의 구현 변경 시 수정해야 하는 구현 객체들이 모두 변경되야 한다.

예시 코드

protocol Vehicle {
    var name: String { get }
    var id: String { get }
    var wheel: Int { get }
}

struct Car: Vehicle {
    var name: String = "차"
    var id: String = "1"
    var wheel: Int = 4
}

struct Scooter: Vehicle {
    var name: String = "스쿠터"
    var id: String = "2"
    var wheel: Int = 2
}

protocol FactoryProtocol {
    func createVehicle() -> Vehicle
}

struct ScooterFactory: FactoryProtocol {
    func createVehicle() -> Vehicle {
        return Scooter()
    }
}

struct CarFactory: FactoryProtocol {
    func createVehicle() -> Vehicle {
         return Car()
    }
}

struct Client {
    let factory: FactoryProtocol
    
    init(factory: FactoryProtocol) {
        self.factory = factory
    }
}

let client1 = Client(factory: CarFactory())
let car = client1.factory.createVehicle()

let client2 = Client(factory: ScooterFactory())
let scooter = client2.factory.createVehicle()

내 생각

  • 객체 자체와 객체를 만들 수 있는 팩토리 모두 추상화를 통해 실제 클라이언트는 팩토리에만 의존하고 있고 어떤 객체를 만들지에 대해 의존성 주입을 해주기 때문에 실제 사용한하는 객체의 변경이 있더라도 클라이언트엔 영향이 가지 않을 것 같다.
  • 공통점을 가진 여러가지 객체를 사용할 때 좋을 듯 하다. Repository 패턴도 이와 비슷하지 않을까..?

참고

profile
I Am Groot

1개의 댓글

comment-user-thumbnail
2023년 9월 8일

associatedType이 있는 protocol의 경우에 제네릭으로 해결할 수 있지만,
some 키워드를 통해 추상화된 형태로 내보낼 수 있다는 지점에서...
some 키워드가 추상 팩토리를 구현하는데 도움이 되기도 하겠네요 :)

답글 달기