You will be fine

<디자인패턴입문> 4. Prototype 패턴

by BFine
반응형

www.yes24.com/Product/Goods/2918928

 

Java 언어로 배우는 디자인 패턴 입문

이 책은 디자인 패턴의 입문서입니다. GoF가 정리한 23개의 디자인 패턴을 하나씩 다루면서 객체 지향을 잘 모르는 초보자도 이해하기 쉽도록 정리하고 있습니다. 단순한 이론이나 논리을 제시하

www.yes24.com

 

가. 무엇인가

 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로 분리하게 된다면 단순히 ProductProductStore만 하나로 가져가면 된다.

 

 b. 클래스이름은 속박인가? 

  -  소스내부 클래스 이름을 쓰는 것은 나쁜것만은 아니지만 해당 클래스와 분리해서 재이용 할 수 없다!

 

 c. Java의 clone 

  -  복사 대상이 되는 클래스는 Cloneable 인터페이스를 구현해야한다.

  -  Cloneable은 단순히 clone에 의해 복사할수 있다라는 표시로 이용되는 marker interface이다.

  -  유의할점은 clone은 shallow copy로 참조만 복사될뿐 요소하나하나가 복사되는 것은 아니다.

       => deep copy가 필요한 경우 clone을 Override해서 사용해야한다. 

  -  또한 생성자를 호출하는 것이 아니라는 부분도 인지해야한다.

 

반응형

블로그의 정보

57개월 BackEnd

BFine

활동하기