디자인패턴

[Java] Prototype 패턴

ZzangHo 2022. 4. 12. 23:41
728x90

디자인 패턴 공부용으로 블로그에 기록을 해본다.

공부에 참고한 자료로는 "Java 언어로 배우는 디자인 패턴 입문" 을 참고 하였다.

 

정의

Prototype이란 '원형' 이나 '모범' 이라는 의미이다. 원형이 되는 인스턴스, 모범이 되는 인스턴스를 기초로 새로운 인스턴스를 만든다.

 

Prototype 패턴이 필요한 3가지 이유

  1. 종류가 너무 많아서 클래스로 정리할 수 없는 경우
  2. 클래스로부터 인스턴스 생성이 어려운 경우
  3. framework와 생성하는 인스턴스를 분리하고 싶은 경우

 

예제 프로그램

문자열을 테두리 선으로 감싸거나 밑줄을 표시하는 프로그램

 

클래스 설명

패키지 이름 해설
framework Product 추상 메소드 use와 createClone이 선언되어 있는 인터페이스
Manager createClone을 사용해서 인스턴스를 복제하는 클래스
Anonymous MessageBox 문자열을 테두리로 표시하는 클래스, use와 createClone을 구현
UnderlinePen 문자열에 밑줄을 표시하는 클래스, use와 createClone을 구현
Main 동작 테스트용 클래스

 

Product 인터페이스

Product 인터페이스에서는 Cloneable 인터페이스를 상속하고 있으며, 복제를 가능하게 한다.

package Prototype;

public interface Product extends Cloneable{
    public abstract void use(String s);
    public abstract Product createClone();
}

 

Manager 클래스

Manager 클래스는 Product 인터페이스를 이용해서 인스턴스의 복제를 실행하는 클래스이다.

register 메소드에서 제품의 이름과 Product 인터페이스가 주어지면 그 한 쌍을 showcase에 등록한다. 여기에서 인수에 전달되는 Product형의 proto는 무엇인지 모르지만 Product 인터페이스를 구현한 클래스의 인스턴스라는 것을 알 수 있다.

 

여기서 중요한 점은 Manager 클래스에서 우리가 다음에 구현할 MessageBox, UnderlinePen 클래스의 네임이 나오지 않는 다는 것이다. 클래스 네임이 명시되어 있지 않다는 것은 해당 클래스와는 독립적으로 수정할 수 의미한다.

package Prototype;

import java.util.HashMap;

public class Manager {
    private HashMap showcase = new HashMap();
    public void register(String name, Product product) {
        showcase.put(name, product);
    }

    public Product create(String name) {
        Product p = (Product) showcase.get(name);
        return p.createClone();
    }
}

 

MessageBox 클래스

MessageBox 클래스는 Product 인터페이스를 구현하고 있으며 createClone 메소드에서 복제를 할 수 있도록 구현해주고 있다.

clone 메소드로 복사 가능한 것은 java.lang.Cloneable 인터페이스를 구현하고 있는 클래스뿐이다.

만약 이 인터페이스가 구현되고 있지 않은 경우에는 CloneNotSupportedException이 발생하기 때문에 try catch로 잡아 둘 필요가 있다.

package Prototype;

public class MessageBox implements Product {
    private char decochar;

    public MessageBox(char decochar) {
        this.decochar = decochar;
    }

    @Override
    public void use(String s) {
        int length = s.getBytes().length;
        for (int i = 0; i < length + 4; i++) {
            System.out.print(decochar);
        }
        System.out.println(" ");
        System.out.println(decochar + " " + s + " " + decochar);
        for (int i = 0; i < length + 4; i++) {
            System.out.print(decochar);
        }
        System.out.println(" ");
    }

    @Override
    public Product createClone() {
        Product product = null;
        try {
            product = (Product) clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return product;
    }
}

 

UnderlinePen 클래스

package Prototype;

public class UnderlinePen implements Product {
    private char ulchar;

    public UnderlinePen(char ulchar) {
        this.ulchar = ulchar;
    }

    @Override
    public void use(String s) {
        int length = s.getBytes().length;
        System.out.println("\"" + s + "\"");
        System.out.print(" ");
        for (int i = 0; i < length; i++) {
            System.out.print(ulchar);
        }
        System.out.println(" ");

    }

    @Override
    public Product createClone() {
        Product product = null;
        try {
            product = (Product) clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return product;
    }
}

 

Main 클래스

package Prototype;

public class Main {
    public static void main(String[] args) {
        Manager manager = new Manager();
        UnderlinePen underlinePen = new UnderlinePen('_');
        MessageBox messageBox1 = new MessageBox('*');
        MessageBox messageBox2 = new MessageBox('/');

        manager.register("strong message", underlinePen);
        manager.register("warning box", messageBox1);
        manager.register("slash box", messageBox2);

        Product p1 = manager.create("strong message");
        p1.use("Hello, world");

        Product p2 = manager.create("warning box");
        p2.use("Hello, world");

        Product p3 = manager.create("slash box");
        p3.use("Hello, world");
    }
}

Main을 실행해보면 아래와 같이 출력 된다.

"Hello, world"
 ____________ 
**************** 
* Hello, world *
**************** 
//////////////// 
/ Hello, world /
//////////////// 

Process finished with exit code 0

'디자인패턴' 카테고리의 다른 글

[Java] Builder 패턴  (0) 2022.04.25
[Java] Singleton 패턴  (0) 2022.04.12
[Java] Factory 패턴  (0) 2022.04.05
[Java] Template Method 패턴  (0) 2022.04.03
[Java] Adapter 패턴  (0) 2022.04.03