사용의도
- 미리 원형(Prototype) 으로 초기화 해 둔 뒤, 이를 복제해서 사용합니다.
- boilerplatecode 를 제거할 수 있습니다.
- 이를 복제해서 사용하므로써, 인스턴스화 하는 클래스를 런타임에 초기화하여 생성합니다.
미리 원형으로 초기화한다. | 어떠한 객체를 미리 생성해두는 것을 말합니다. |
이를 복제해서 사용한다. | 생성해둔 객체를 복사하여 사용한다는 뜻입니다. |
인스턴스화 하는 클래스를 런타임에 초기화하여 생성한다. | 복제한 클래스들 여러개를 합성(Composition) 하여 갖고있는 인스턴스를 런타임에 생성한다는 뜻입니다. |
구조
예시) 비행기의 부품을 선택하여, 완제품인 비행기를 만드는 게임
완제품인 비행기 를 만들기위해서 부품으로
- 엔진
- 날개
를 선택해야 한다고 가정합니다.
@AllArgsConstructor
public class AirPlane {
private Wing wing;
private Engine engine;
}
이러한 과정에서 우리는 날개와 엔진을 생성하는 코드를 날개와 엔진에 위임한 뒤
public abstract class Engine {
protected abstract Engine clone();
}
public abstract class Wing {
protected abstract Wing clone();
}
이를 선택하여 비행기를 만드는 팩토리(registry)를 선언합니다.
- 팩토리(registry)는 미리 모든 객체들을 갖고있도록 합니다.
public class AirplaneFactory {
private static HashMap<String, Wing> wingHashMap = new HashMap<>();
private static HashMap<String, Engine> engineHashMap = new HashMap<>();
static {
wingHashMap.put("cheapWing", new CheapWing());
wingHashMap.put("expensiveWing", new ExpensiveWing());
engineHashMap.put("cheapEngine", new CheapEngine());
engineHashMap.put("expensiveEngine", new ExpensiveEngine());
}
public static AirPlane createAirplane(String wingName, String engineName) {
return new AirPlane(
wingHashMap.get(wingName),
engineHashMap.get(engineName));
}
}
엔진과 날개에는 각 각 비싼 부품, 싼 부품이 있다고 가정할 때
public class CheapEngine extends Engine {
@Override
protected Engine clone() {
return new CheapEngine();
}
}
public class CheapWing extends Wing {
@Override
protected Wing clone() {
return new CheapWing();
}
}
public class ExpensiveEngine extends Engine {
@Override
protected Engine clone() {
return new ExpensiveEngine();
}
}
public class ExpensiveWing extends Wing {
@Override
protected Wing clone() {
return new ExpensiveWing();
}
}
사용자 입장에서는 버튼클릭을 통해서
- 싼 날개와 비싼 엔진을 클릭해서 전달됐다면 아래와같이 비행기를 생성할 수 있습니다.
public class AirplanePrototypeTest {
@Test
void test() {
final AirPlane airplane =
AirplaneFactory.createAirplane("cheapWing", "expensiveEngine");
airplane.doSomething()....
}
}
아니.. 그러면 clone 안하고 바로 미리 생성한 곳에서 뽑아서 새로만들어주면 되는거아닌가요?
- 개인적으로는 clone 메소드 이후에,
- initial하는 과정을 추가하므로써,
- 해당 객체를 복제하는 역할을 그 객체에 위임하는 과정을 통해서 해당 과정을 서비스로직에서 드러나지 않게해서
- 객체의 책임을 명확하게 하는 것이 이유라고 생각합니다.
- initial하는 과정을 추가하므로써,
- 아래와 같이 initialize 하는 과정을 수행하면 ExpensiveEngine 에 책임을 확실하게 부여할 수 있겠죠
- 나중에 ExpensiveEngine의 initial 과정이 변하면 아래의 클래스만 수정하면 될 것입니다.
public class ExpensiveEngine extends Engine {
@Override
protected Engine clone() {
final ExpensiveEngine expensiveEngine = new ExpensiveEngine();
expensiveEngine.initialize();
return expensiveEngine;
}
public void initialize() {
doSomething...
}
}
'디자인패턴' 카테고리의 다른 글
브릿지 패턴 (Bridge Pattern) (0) | 2021.06.18 |
---|---|
어댑터 패턴 (Adapter pattern) (0) | 2021.06.12 |
단일체 패턴 (Singleton Pattern) (0) | 2021.06.05 |
팩토리 메서드 패턴 (Factory Method Pattern) (0) | 2021.05.29 |
추상팩토리 패턴 (Abstract Factory Pattern) (0) | 2021.05.22 |