생성 패턴: Abstract Factory와 Builder
추상 팩토리 패턴의 고전적 구현과 파이썬다운 구현을 비교하고, 빌더 패턴으로 복잡한 객체를 단계별로 생성하는 방법을 정리한다.
시리즈 · 디자인 패턴2 / 2
- Facade 패턴
- 생성 패턴: Abstract Factory와 Builder
추상 팩토리 패턴 (Abstract Factory)
여러 객체로 구성된 복합 객체를 만들어야 하고, 포함된 객체들이 모두 특정한 한 계통에 속할 때 사용한다.
고전적인 추상 팩토리
DiagramFactory: 일반 텍스트 형태의 다이어그램을 만드는 팩토리SvgDiagramFactory: SVG 그래픽 형태의 다이어그램을 만드는 팩토리

create_diagram은 다이어그램 팩토리를 인자로 받아 다이어그램을 생성한다. 다이어그램 팩토리 인터페이스만 지원하면 어떤 종류의 팩토리가 들어와도 상관없다.

두 팩토리 구현의 유일한 차이는 반환하는 객체의 타입이다. 한쪽은 Diagram 계열, 다른 쪽은 SvgDiagram 계열의 객체를 반환한다.
파이썬다운 방법
고전적인 구현에는 다음과 같은 문제가 있다.
- 어느 팩토리도 상태를 가질 필요가 없으므로 굳이 인스턴스를 생성할 필요가 없다.
SvgDiagramFactory와DiagramFactory의 코드가 거의 같고, 차이는 반환하는 인스턴스의 타입뿐이다.- 이름 충돌을 피하려고 SVG 쪽 클래스에 접두어를 붙여야 했다. (예:
SvgRectangle)
해결 방법은 두 가지다.
Diagram,Rectangle,Text클래스를DiagramFactory의 내부 클래스로 만든다.- 각 팩토리 메서드를
classmethod로 만든다.

이렇게 하면 DiagramFactory를 상속받은 SvgDiagramFactory는 make_diagram, make_rectangle 같은 메서드를 더 이상 오버라이드할 필요가 없다. 내부 클래스만 바꿔 정의하면 된다. 또한 classmethod이므로 팩토리 객체를 생성하지 않고도 다이어그램 인스턴스를 얻을 수 있다.
빌더 패턴 (Builder)
- 복잡한 객체를 만드는 일을 돕는다.
- 객체가 복잡하면 생성 과정을 단계별로 나눌 필요가 있다.
다양한 매개변수 조합으로 User를 생성해야 하면, 아래처럼 생성자가 조합마다 계속 늘어난다.

이럴 때는 빌더로 User 객체를 만드는 편이 훨씬 효율적이다.

파이썬 예제: 폼 빌더
각 폼을 생성한 다음 적절한 파일에 저장하는 예제다.

create_login_form()에 적절한 빌더 객체를 인자로 전달해 호출한다.

HtmlFormBuilder와 TkFormBuilder는 모두 추상 기반 클래스인 AbstractFormBuilder를 상속한다.

메타클래스로 abc.ABCMeta를 지정하면 해당 클래스는 인스턴스를 만들 수 없고 추상 기반 클래스로만 쓸 수 있다. 다만 실행 시 약간의 비용이 더 든다.
그래서 많은 파이썬 프로그래머는 덜 엄격한 방법을 쓴다. 메타클래스를 쓰지 않고, 해당 클래스를 추상 기반 클래스로만 사용해야 한다고 문서화하는 것이다. 강제성이 없으므로 문제가 될 여지는 있다.
Reference
- 파이썬 인 프랙티스
- Baeldung