파이썬 디자인 패턴 - 생성 디자인 패턴 - 추상 팩터리 패턴
04 Aug 2018 | python designpattern 생성디자인패턴
1장 파이썬 생성 디자인 패턴
- 생성 디자인 패턴은 객체를 생성하는 방법에 대한 패턴
- 보통은 객체를 생성할 때 생성자를 활용
- 생성 디자인 패턴을 활용하면 객체 생성을 유연하게 할 수 있다
1-1. 추상 팩터리 패턴
- 여러 객체로 구성된 복합 객체를 만들어야 하는데, 포함된 객체가 모두 틀별한 한 계통 일 때 사용 가능.
- 예를 들어, Mac, Xfce, Window에서 위젯을 만들어주는 3 개의 concrete subclass factory 가 있는 Abstract widget factory가 있다고하자.
- 세 구상 팩터리 모두 동일한 객체를 생성하는 메서드를 제공하지만, 각 결과물은 플랫폼에 따라 다른 스타일을 띠어야 한다.
- 이러한 메서드를 활용하면 팩터리 인스턴스를 인자로 받아 해당 인자에 따라 다른 대화상자를 만드는 제네릭함수를 만들 수 있다.
1.1 고전적인 추상 팩터리
- diagram1.py 와 diagram2.py 의 동일 부분을 보자. 공통적으로 txtDiagram과 svgDiagram을 생성하여 save한다.
- 위 함수는 diagram factory 만을 받아 이를 활용해 요청받은 다이어그램을 생
- 다이어그램 팩터리 인터페이스(make_diagram, make_rectangle, make_text…의 def를 지원)를 지원하는 한 어떤 종류의 팩터리를 인자로 받은 관계 없음
- 패턴 이름에 추상이란 단어가 포함돼 있음에도 한 클래스가 인터페이스를 지원하는 기반 클래스이자 그 자체로 구상 클래스인 경우는 흔히 접할 수 있다. (DiagramFactory 클래스가 기반 클래스이지만, 내부에 모든 def가 구현되어 있음) (추상클래스? 구상클래스? 정리본 )
- DiagramFactory의 make_diagram() 과의 유일한 차이점은 SvgDiagram 객체를 반환한다는 것 뿐이다. 나머지 메서에도 동일하다
- 각 클래스가 동일한 인터페이스를 제공하긴 하지만 (Diagram과 SvgDiagram 모두 동일한 메서드를 가지고 있음) 일반 텍스트 버전의 Diagram, Rectangle, Text 클래스 구현은 Svg버전의 그것과는 근본적으로 다르다.
- 이는 서로 다른 계열의 클래스 (즉, Rectangle과 SvgText)를 혼합할 수 없음을 의미, 이것이 팩터리 클래스에 자동적으로 적용되는 제약사항
- 일반 텍스트 다이어그램 객체는 내부데이터를
공백, +, -, |
로 구성된 한 글자짜리 문자열 리스트로 가지고 있다. 그것들을 지정된 위치에 맞춰 생성한다.
1-1-2. 더 파이썬다운 추상 팩터리
-
위의 diagram1.py의 구현에는 몇가지 미흡한 점이 있다.
- 어느 팩터리는 상태 정보를 가지고 있을 필요가 없으므로, 실제 팩터리 인스턴스를 생성할 필요가 없다.
- SvgDiagramFactory 코드는 DiagramFactory 코드와 거의 동일하고, 유일한 차이는 Text 대신 SvgText 인스턴스를 돌려준다는 것 뿐이라 불필요한 중복이 존재한다.
- 최상위 네임스페이스에 모든 클래스가 모여있다, 하지만 우리는 단지 두개의 팩터리에만 접근하면 된다. 게다가 이름의 충돌을 피하기위해 Svg클래스 이름에 접두어를 붙여야만 했는데 지저분하다.
-
diagram2.py에서 위의 미흡한 부분을 모두 해결할 예정
- Diagram, Rectangle, Text 클래스를 DiagramFactory 클래스의 내부 클래스로 만든다. 이렇게 하면 클래스에 DiagramFactory.Diagram 과 같은 식으로 접근 가능하므로, SvgDiagramFactory내에 Diagram 과 같이 이름을 동일하게 만들 수 있다.(클래스 이름 충돌 x)
- 최상위 네임스페이스에는
main(), create_diagram(), DiagramFactory(), SvgDiagramFactory()
만이 남는다.
make_...()
메서드는 이제 모두 클래스메서드이다.
- 이는 이 메서드를 호출할 때 (일반 메서드에 self가 전달되는 것과 달리) 첫 번째 인자로 클래스 정보를 전달한다는 것을 의미
- 따라서
DiagramFactory.make_text()
를 호출하면 DiagramFactory가 Class 값으로 전달되 DiagramFactory.Text
객체가 생성되어 반환된다.
- 이러한 변화 때문에
DiagramFactory
를 상속한 하위 클래스인 SvgDiagramFactory
에는 더이상 make_...()
메서드가 필요하지 않다.
- 예를들어
SvgDiagramFactory.make_rectangle()
호출 -> SvgDiagramFactory
에 해당 메서드가 없음 -> 상위(기반) 클래스의 DiagramFactory.make_rectangle
메서드를 대신 호출 -> 이때 Class 값에는 SvgDiagramFactory
가 전달 -> SvgDiagramFactory.Rectangle
객체가 생성되어 반환
- 나머지 코드는 이전과 거의 동일하다. 핵심적인 변경사항은 이제 상수값과 팩터리가 아닌 클래스들이 모두 팩터리 안에 내장됐으므로 앞으로 이것들을 사용하려면 팩터리 이름을 붙여야 한다는 것이다.
- 위와 같이 변경되었다.
1장 파이썬 생성 디자인 패턴
- 생성 디자인 패턴은 객체를 생성하는 방법에 대한 패턴
- 보통은 객체를 생성할 때 생성자를 활용
- 생성 디자인 패턴을 활용하면 객체 생성을 유연하게 할 수 있다
1-1. 추상 팩터리 패턴
- 여러 객체로 구성된 복합 객체를 만들어야 하는데, 포함된 객체가 모두 틀별한 한 계통 일 때 사용 가능.
- 예를 들어, Mac, Xfce, Window에서 위젯을 만들어주는 3 개의 concrete subclass factory 가 있는 Abstract widget factory가 있다고하자.
- 세 구상 팩터리 모두 동일한 객체를 생성하는 메서드를 제공하지만, 각 결과물은 플랫폼에 따라 다른 스타일을 띠어야 한다.
- 이러한 메서드를 활용하면 팩터리 인스턴스를 인자로 받아 해당 인자에 따라 다른 대화상자를 만드는 제네릭함수를 만들 수 있다.
1.1 고전적인 추상 팩터리
- diagram1.py 와 diagram2.py 의 동일 부분을 보자. 공통적으로 txtDiagram과 svgDiagram을 생성하여 save한다.
- 위 함수는 diagram factory 만을 받아 이를 활용해 요청받은 다이어그램을 생
- 다이어그램 팩터리 인터페이스(make_diagram, make_rectangle, make_text…의 def를 지원)를 지원하는 한 어떤 종류의 팩터리를 인자로 받은 관계 없음
- 패턴 이름에 추상이란 단어가 포함돼 있음에도 한 클래스가 인터페이스를 지원하는 기반 클래스이자 그 자체로 구상 클래스인 경우는 흔히 접할 수 있다. (DiagramFactory 클래스가 기반 클래스이지만, 내부에 모든 def가 구현되어 있음) (추상클래스? 구상클래스? 정리본 )
- DiagramFactory의 make_diagram() 과의 유일한 차이점은 SvgDiagram 객체를 반환한다는 것 뿐이다. 나머지 메서에도 동일하다
- 각 클래스가 동일한 인터페이스를 제공하긴 하지만 (Diagram과 SvgDiagram 모두 동일한 메서드를 가지고 있음) 일반 텍스트 버전의 Diagram, Rectangle, Text 클래스 구현은 Svg버전의 그것과는 근본적으로 다르다.
- 이는 서로 다른 계열의 클래스 (즉, Rectangle과 SvgText)를 혼합할 수 없음을 의미, 이것이 팩터리 클래스에 자동적으로 적용되는 제약사항
- 일반 텍스트 다이어그램 객체는 내부데이터를
공백, +, -, |
로 구성된 한 글자짜리 문자열 리스트로 가지고 있다. 그것들을 지정된 위치에 맞춰 생성한다.
1-1-2. 더 파이썬다운 추상 팩터리
-
위의 diagram1.py의 구현에는 몇가지 미흡한 점이 있다.
- 어느 팩터리는 상태 정보를 가지고 있을 필요가 없으므로, 실제 팩터리 인스턴스를 생성할 필요가 없다.
- SvgDiagramFactory 코드는 DiagramFactory 코드와 거의 동일하고, 유일한 차이는 Text 대신 SvgText 인스턴스를 돌려준다는 것 뿐이라 불필요한 중복이 존재한다.
- 최상위 네임스페이스에 모든 클래스가 모여있다, 하지만 우리는 단지 두개의 팩터리에만 접근하면 된다. 게다가 이름의 충돌을 피하기위해 Svg클래스 이름에 접두어를 붙여야만 했는데 지저분하다.
-
diagram2.py에서 위의 미흡한 부분을 모두 해결할 예정
- Diagram, Rectangle, Text 클래스를 DiagramFactory 클래스의 내부 클래스로 만든다. 이렇게 하면 클래스에 DiagramFactory.Diagram 과 같은 식으로 접근 가능하므로, SvgDiagramFactory내에 Diagram 과 같이 이름을 동일하게 만들 수 있다.(클래스 이름 충돌 x)
- 최상위 네임스페이스에는
main(), create_diagram(), DiagramFactory(), SvgDiagramFactory()
만이 남는다.
make_...()
메서드는 이제 모두 클래스메서드이다.- 이는 이 메서드를 호출할 때 (일반 메서드에 self가 전달되는 것과 달리) 첫 번째 인자로 클래스 정보를 전달한다는 것을 의미
- 따라서
DiagramFactory.make_text()
를 호출하면 DiagramFactory가 Class 값으로 전달되DiagramFactory.Text
객체가 생성되어 반환된다.
- 이러한 변화 때문에
DiagramFactory
를 상속한 하위 클래스인SvgDiagramFactory
에는 더이상make_...()
메서드가 필요하지 않다.- 예를들어
SvgDiagramFactory.make_rectangle()
호출 ->SvgDiagramFactory
에 해당 메서드가 없음 -> 상위(기반) 클래스의DiagramFactory.make_rectangle
메서드를 대신 호출 -> 이때 Class 값에는SvgDiagramFactory
가 전달 ->SvgDiagramFactory.Rectangle
객체가 생성되어 반환
- 예를들어
- 나머지 코드는 이전과 거의 동일하다. 핵심적인 변경사항은 이제 상수값과 팩터리가 아닌 클래스들이 모두 팩터리 안에 내장됐으므로 앞으로 이것들을 사용하려면 팩터리 이름을 붙여야 한다는 것이다.
- 위와 같이 변경되었다.
Comments