<디자인패턴입문> 4. Prototype 패턴
by BFinewww.yes24.com/Product/Goods/2918928
가. 무엇인가
a. new를 쓰지않아!
- 자바는 new 라는 키워드를 사용해서 인스턴스를 생성한다. 이경우 반드시 클래스 이름을 지정해야한다.
- 그렇지만 클래스 이름을 지정하지 않고 인스턴스를 생성해야 할때가 있다.
1. 종류가 너무 많아 클래스로 정리되지 않는 경우
2. 사용자 조작으로 다이나믹하게 생성해야 할 경우
3. framework를 특정클래스에 의존하지 않도록 하고싶은 경우
나. 만들어본 예제
a. Prototype(원형) 역할
- Product 인터페이스는 Cloneable을 상속한다.
=> Cloneable의 내부는 비어있지만 상속하지 않고 clone할경우 CloneNotSupportedException 발생한다.
public interface Product extends Cloneable{
void unboxing();
Product createClone();
}
b. ConcreatePrototype(구체적인 원형) 역할
- 인스턴스를 복사해서 새로운 인스턴스를 만드는 메서드를 실제로 구현한다.
public class SamsungTablet implements Product{
@Override
public void unboxing() {
System.out.println("---- UnBoxing 중 ----");
System.out.println("갤럭시 S7+, 충전기");
System.out.println("펜은 포함입니다.");
System.out.println("---- UnBoxing 끝 ----");
}
@Override
public Product createClone() {
Product product = null;
try{
product = (Product) clone();
}catch (Exception e){
e.printStackTrace();
}
return product;
}
}
public class AppleTablet implements Product{
@Override
public void unboxing() {
System.out.println("---- UnBoxing 중 ----");
System.out.println("아이패드프로 5세대, 충전기 ");
System.out.println("펜은 별도입니다.");
System.out.println("---- UnBoxing 끝 ----");
}
@Override
public Product createClone() {
Product product = null;
try{
product = (Product) clone();
}catch (Exception e){
e.printStackTrace();
}
return product;
}
}
c. Client 역할
- 인스턴스를 복사하는 메서드를 이용해 새로운 인스턴스를 만든다.
public class ProductStore{
private Map<Manufacturer,Product> store = new HashMap<>();
public void save(Manufacturer manufacturer, Product product){
store.put(manufacturer,product);
}
public Product buy(Manufacturer manufacturer){
Product p = store.get(manufacturer);
return p.createClone();
}
}
d. Main
public class Main {
public static void main(String[] args) {
ProductStore productStore = new ProductStore();
productStore.save(Manufacturer.APPLE, new AppleTablet());
productStore.save(Manufacturer.SAMSUNG, new SamsungTablet());
Product product = productStore.buy(Manufacturer.APPLE);
Product product2 = productStore.buy(Manufacturer.SAMSUNG);
product.unboxing();
product2.unboxing();
}
}
// 실행
---- UnBoxing 중 ----
아이패드프로 5세대, 충전기
펜은 별도입니다.
---- UnBoxing 끝 ----
---- UnBoxing 중 ----
갤럭시 S7+, 충전기
펜은 포함입니다.
---- UnBoxing 끝 ----
다. 정리
a. 장점
- 위의 예제에서 Manufacturer가 몇백개라면 일반적인 new를 사용할 경우 어떤 클래스에 수백개의 클래스가
종속되는 끔찍한 일이 발생하는 것을 방지한다.
- 또한 ProductStore 클래스를 보면 구현클래스에 대한 결합이 전혀 없는 것을 볼 수 있다.
=> framework로 분리하게 된다면 단순히 Product와 ProductStore만 하나로 가져가면 된다.
b. 클래스이름은 속박인가?
- 소스내부 클래스 이름을 쓰는 것은 나쁜것만은 아니지만 해당 클래스와 분리해서 재이용 할 수 없다!
c. Java의 clone
- 복사 대상이 되는 클래스는 Cloneable 인터페이스를 구현해야한다.
- Cloneable은 단순히 clone에 의해 복사할수 있다라는 표시로 이용되는 marker interface이다.
- 유의할점은 clone은 shallow copy로 참조만 복사될뿐 요소하나하나가 복사되는 것은 아니다.
=> deep copy가 필요한 경우 clone을 Override해서 사용해야한다.
- 또한 생성자를 호출하는 것이 아니라는 부분도 인지해야한다.
'개발서적 > 디자인패턴입문' 카테고리의 다른 글
<디자인패턴입문> 6. Abstract Factory 패턴 (0) | 2021.04.26 |
---|---|
<디자인패턴입문> 5. Bridge 패턴 (0) | 2021.04.25 |
<디자인패턴입문> 3. Template Method 패턴 (0) | 2021.04.22 |
<디자인패턴입문> 2. Adapter 패턴 (0) | 2021.04.21 |
<디자인패턴입문> 1. Iterator 패턴 (0) | 2021.03.28 |
블로그의 정보
57개월 BackEnd
BFine