[디자인 패턴 17편] 디자인 패턴 총 정리. 생성편
지금까지 공부하며 정리한 GoF 디자인 패턴을 총 정리해보려고 한다.
최대한 간결하고 필요한 것만 남겨본다.
여기서는 구체적인 구현 코드는 적지않고, 이미 패턴이 구현된 객체들을 사용하는 코드만 적겠다.
사용자 코드만 봐도 어떻게 작동하는지 알 수 있을거라 생각한다.
(또 이렇게 사용자 코드만 봐도 이해가 가도록 구현해놓는 코드가 좋은 코드, 패턴이라고 생각한다.)
구현 코드는 대충 참고만할 수 있게, 클래스 다이어그램만 남겨둔다.
먼저 객체의 생성에 대해 다루는 생성편이다.
싱글톤 (Signleton)
코드 내 어디서든, 오직 하나의 인스턴스만 사용할 수 있도록 객체를 생성하는 방법이다.
즉 객체는 여러 번 생성되지 않고, 최초 하나의(Single) 인스턴스만 생성하고, 이후에는 이 인스턴스를 참조하게 된다.
전역적으로 하나의 인스턴스만 사용, 참조해야하는 경우에 사용한다.
사용 예시
# 보통, 싱글톤 객체의 .get_instance() 로 인스턴스를 받아온다.
singleton_1 = Singleton.get_instance()
singleton_2 = Singleton.get_instance()
# 이렇게 받아온 두 인스턴스는 동일한 인스턴스다.
singleton_1 == singleton_2 # True
구현 구조
구체적인 동작은 [디자인 패턴 2편] 생성 패턴, 싱글톤(Singleton) 참고.
활용 예시
- DB 커넥션과 Pool 을 담당하는 인스턴스
- 시스템 전역의 로깅을 담당하는 로거
프로토타입 (Prototype)
기존의 인스턴스를 그대로 복제(clone) 하여 새로운 객체를 생성하는 방법이다.
즉, 하나의 인스턴스를 사용하는 싱글톤과는 반대되는 개념이다.
사용 예시
# 보통, 프로토타입 객체의 .clone() 으로 인스턴스를 복사한다.
original = Prototype()
prototype = original.clone()
# 이렇게 받아온 두 인스턴스는 동일한 객체는 아니지만, 내부 데이터는 같다.
original == prototype # False
original.data == prototype.data # True
구현 구조
활용 예시
- DB 로부터 얻어온 데이터 인스턴스를 동일하게 하나 더 만들어야 하는 경우
- DB 에 연결하는 것 보다 이렇게 코드로 처리 하는게 일반적으로 cost 가 더 저렴하다.
- 인스턴스 복사가 자주 필요한 어디든..?
팩토리 (Factory)
인스턴스를 만들어내는 공장(Factory) 를 통해 객체를 생성하는 방법이다.
즉, 인스턴스를 직접 생성해내지 않고, 공장에서 제공하는 메쏘드를 통해 생성해낸다.
사용자는 객체를 생성하고 싶을 때, 공장에서 제공하는 메쏘드만 알고있으면 된다.
그 외 구체적으로 인스턴스가 어떻게 생성되는지 몰라도 된다.
한 집합 내에 있는 클래스들의 생성을 한 곳에서 처리하고 싶을 때 사용한다.
사용 예시
# 보통, Factory 객체의 `get` 메쏘드의 파라미터로 생성할 객체의 타입을 넘겨준다.
samsung_keyboard = KeyboardFactory.get_keyboard("samsung")
lg_keyboard = KeyboardFactory.get_keyboard("lg")
# 생성된 객체는 다음과 같이 구체적인 클래스 인스턴스다.
samsung_keyboard # SamsungKeyboard
lg_keyboard # LgKeyboard
구현 구조
구체적인 동작은 [디자인 패턴 3편] 생성 패턴, 팩토리 메쏘드 (Factory) 참고.
활용 예시
- 삼성, LG 키보드를 만드는 키보드 팩토리
- 개념 상 같은 분류의 클래스들의 생성을 모아서 처리하는게 편할 때
추상 팩토리 (Abstract Factory)
공장을 만들어내는 상위 공장을 먼저 정의하고, 여기서 구체적인 공장을 만든 후, 이 공장에서 객체를 생성하는 방법이다.
즉, 팩토리의 위에 이 팩토리를 만드는 팩토리가 있다고 생각하면 된다.
그 외 특징은 팩토리 패턴과 같다.
사용 예시
# 키보드 팩토리의 팩토리(추상 팩토리)를 통해 키보드 팩토리를 얻는다.
CommonKeyboardFactory = AbstarctKeyboardFactory.get_keyboard_factory("common")
# 이후는 팩토리 패턴과 동일하다.
samsung_common_keyboard = CommonKeyboardFactory.get_keyboard("samsung")
lg_common_keyboard = CommonKeyboardFactory.get_keyboard("lg")
samsung_keyboard # SamsungCommonKeyboard
lg_keyboard # LgCommonKeyboard
구현 구조
구체적인 동작은 [디자인 패턴 5편] 생성 패턴, 추상 팩토리 메쏘드 (Abstract Factory) 참고.
활용 예시
- 기계식 키보드 공장와 일반 키보드공장을 만드는 키보드 추상 팩토리
- 팩토리보다 조금 더 복잡한, 혹은 구조적인 계층을 갖는 클래스들의 생성을 처리해야 할 때.
빌더 (Builder)
객체를 생성할 때 필요한 파라미터가 많은 경우, 각 파라미터가 무엇을 의미하는지 알기 힘들 수 있다.
이럴 때, 빌더라는 형태를 통해 파라미터 의미를 명확히하여 생성할 수 있다.
이건 아래의 구체적인 사용 예를 보면 된다.
사용 예시
# 빌더 패턴 사용 전 (경우 1)
WebBrowser browser = WebBrowser(True, FlashPlugin(), True, 10);
# 빌더 패턴을 사용하면 이렇습니다.
WebBrowser browser = BrowserBuilder().
with_ssl(True).
with_flash_plugin().
with_cookie_support().
set_timeout(10).
build()
근데 생각해보니 파이썬에서는 keyword 파라미터를 지원하기 때문에, 굳이 필요 없는 듯 하다.
위 같이 안하고 그냥 다음과 같이 하면 된다.
# 파이썬의 키워드 파라미터 사용
WebBrowser browser = WebBrowser(ssl=True,
flash_plugin=FlashPlugin(),
cookie_support=True,
timeout=10)
여러분 파이썬 쓰세요 ~!
구현 구조
구체적인 동작은 [디자인 패턴 4편] 생성 패턴, 빌더 (Builder) 참고.
활용 예시
- 파라미터가 너무 많아서 의미를 파악하기 힘들 때
정리
- 싱글톤, 프로토타입은 완전히 반대의 개념은 아니지만, 비슷한 집합으로 묶을 수 있지 않을 까싶다.
- 추상 팩토리는 팩토리를 한번 더 요소화 한 것이다.
- 빌더는 파이썬에서 안써도 될듯 하다.
틀린게 있다면 댓글로 알려주세요 :)