의도 : 원형이 되는(Prototype) 인스턴스를 사용하여 생성할 객체 종류를 명시하고 견본을 복사해 새 객체를 생성한다.
원형 패턴은 제품의 생성, 복합 표현 방법에 독립적인 제품을 만들고자 할 때 사용한다.
활용성
제품의 생성, 복합, 포현 방법에 독립적인 제품을 만들고자 할 때 사용한다.
UML
Prototype : 자신을 복제하는 데 필요한 인터페이스를 정의한다.
ConcretePrototype : 자신을 복제하는 연산을 구현한다.
Client : 원형에 자기 자신의 복제를 요청하여 새로운 객체를 생성한다.
결과
구현
c++ 같은 정적 언어에서 유용하다.
Clone을 통해 제품을 복제하여 제품을 생성한다.
UML
Display.java
public class Display {
public Display() {
_producer = "기본";
}
public Display(Display other) {
_producer = other._producer;
}
public void testDisplay() {
System.out.println(_producer + "디스플레이 테스트");
}
public Display Clone() {
return new Display(this);
}
public void Initialize(String producer) {
_producer = producer;
}
protected String _producer;
}
InnerDevice.java
public class InnerDevice {
public InnerDevice() {
_producer = "기본";
}
public InnerDevice(InnerDevice other) {
_producer = other._producer;
}
public void testKeyboardInput() {
System.out.println(_producer + "키보드 입력 테스트");
}
public void testMicrophoneInput() {
System.out.println(_producer + "마이크 입력 테스트");
}
public void Initialize(String producer) {
_producer = producer;
}
public InnerDevice Clone() {
return new InnerDevice(this);
}
private String _producer;
}
Phone.java
public class Phone {
private Display _display;
private InnerDevice _innerDevice;
public Phone() {
_display = new Display();
_innerDevice = new InnerDevice();
}
public Phone(Phone other) {
_display = other._display;
_innerDevice = other._innerDevice;
}
public void Initialize(InnerDevice i, Display d) {
_display = d;
_innerDevice = i;
}
public Display getDisplay() {
return _display;
}
public InnerDevice getInnerDevice() {
return _innerDevice;
}
public Phone Clone() {
return new Phone(this);
}
}
PhonePrototypeFactory.java
public class PhonePrototypeFactory {
PhonePrototypeFactory(Phone p, InnerDevice i_d, Display d) {
_prototypePhone = p;
_prototypeInnerDevice = i_d;
_prototypeDisplay = d;
}
public Phone makePhone() {
return _prototypePhone.Clone();
}
public InnerDevice makeInnerDevice(String producer) {
InnerDevice innerDevice = _prototypeInnerDevice.Clone();
innerDevice.Initialize(producer);
return innerDevice;
}
public Display makeDisplay(String producer) {
Display display = _prototypeDisplay.Clone();
display.Initialize(producer);
return display;
}
private Phone _prototypePhone;
private InnerDevice _prototypeInnerDevice;
private Display _prototypeDisplay;
}
TestPrototypePattern.java
public class TestPrototypePattern {
public static void main(String[] args) {
PhonePrototypeFactory phonePrototypeFactory = new PhonePrototypeFactory(
new Phone(),
new InnerDevice(),
new Display()
);
Phone sPhone = CreateSamsungPhone(phonePrototypeFactory);
Phone iPhone = CreateApplePhone(phonePrototypeFactory);
System.out.println("\n- 삼성 -");
sPhone.getDisplay().testDisplay();
sPhone.getInnerDevice().testMicrophoneInput();
sPhone.getInnerDevice().testKeyboardInput();
System.out.println("\n- 애플 -");
iPhone.getDisplay().testDisplay();
iPhone.getInnerDevice().testMicrophoneInput();
iPhone.getInnerDevice().testKeyboardInput();
}
public static Phone CreateSamsungPhone(PhonePrototypeFactory phonePrototypeFactory) {
Phone phone = phonePrototypeFactory.makePhone();
phone.Initialize(
phonePrototypeFactory.makeInnerDevice("삼성"),
phonePrototypeFactory.makeDisplay("삼성")
);
return phone;
}
public static Phone CreateApplePhone(PhonePrototypeFactory phonePrototypeFactory) {
Phone phone = phonePrototypeFactory.makePhone();
phone.Initialize(
phonePrototypeFactory.makeInnerDevice("애플"),
phonePrototypeFactory.makeDisplay("애플")
);
return phone;
}
}
실행결과
추상 팩토리 패턴과 어떤 면에서 경쟁적인 관계이다. 하지만 함께 사용될 수도 있다. 예를 들어 추상 팩토리 패턴은 원형 집합을 저장하다 필요할 때 복제하여 객체를 반환하도록 사용할 수 있다.
복합체 패턴과 장식자 패턴을 많이 사용해야 하는 설계에서 사용하면 좋을 것이다.
에릭 감마, 리처드 헬름, 랄프 존슨, 존 블리시디스, 『GoF의 디자인 패턴』, 프로텍 미디어, 2015
[디자인패턴] 의존성 주입이란? (0) | 2023.03.12 |
---|---|
[디자인패턴] 팩토리 매서드 (Factory Method Pattern) (0) | 2022.04.02 |
[디자인패턴] 빌더 패턴 (Builder Pattern) (0) | 2022.03.25 |
[디자인패턴] 추상 팩토리 패턴 (Abstract Factory Pattern) (0) | 2022.03.23 |