프로토타입 패턴

이정석·2023년 6월 22일
0

디자인패턴

목록 보기
16/23

프로토타입 패턴이란?

기존 객체를 복제함으로 새로운 객체를 생성하는 패턴으로 같은 객체를 생성하는 책임을 원본 객체가 가지는 구조이다.


문제상황

1. 다음과 같은 Product 클래스가 있다 하자.

class Product {
    private String id;
    private String name;
    private String description;

    public Product(String id, String name, String description) {
        this.id = id;
        this.name = name;
        this.description = description;
    }

    public String getId() { return this.id; }
    public String getName() { return this.name; }
    public String getDescription() { return this.description; }

    public void setId(String id) { this.id = id; }
    public void setName(String name) { this.name = name; }
    public void setDescription(String description) { this.description = description; }
}

2. 원본 Product(p1)과 같은 객체를 만들기 위해서는 모든 속성의 값을 가져와야 한다.

public class Client {
    public static void main(String[] args) {
        Product p1 = new Product("1", "Product1", "This is Product1");
        String originId = p1.getId();
        String originName = p1.getName();
        String originDescription = p1.getDescription();
		
        Product copyp1 = new Product(originId, originName, originDescription);
    }
}

위 상황은 copyp1을 만들기 위해서 기존의 원본 객체인 p1의 모든 값들을 저장하고 같은 값으로 생성한다. 변수가 많거나 데이터를 가져오는데 걸리는 시간이 길다면 이러한 과정은 매우 많은 자원과 시간이 필요할 것이다.

내부 정보와 같은 값을 가지는 객체를 만드는 것을 원본 객체가 하도록 하자


구조

  1. Prototype: 객체를 복제하는 메소드를 정의한 인터페이스로 보통 clone이라는 메소드로 정의한다.
  2. ConcretePrototype: Prototype을 상속받아 실제 복제하는 과정을 구현한 클래스이다.
  3. Client: ConcretePrototype를 가지고 있는 클라이언트로 실제 복제본을 얻기 위해서 ConcretePrototype.clone()을 실행한다.

코드(JAVA)

1. Product

class Product {
    private String id;
    private String name;
    private String description;

    public Product(String id, String name, String description) {
        this.id = id;
        this.name = name;
        this.description = description;
    }

    public Product(Product p) {
        this.id = p.id;
        this.name = p.name;
        this.description = p.description;
    }
    
    public Product clone() {
        return new Product(this);
    }

    public String getId() { return this.id; }
    public String getName() { return this.name; }
    public String getDescription() { return this.description; }

    public void setId(String id) { this.id = id; }
    public void setName(String name) { this.name = name; }
    public void setDescription(String description) { this.description = description; }
}

프로토타입 패턴을 적용한 Product 클래스는 Product(Product p)라는 복사생성자를 통해 복제본을 생성한다. 복사생성자는 clone()에서 호출하며 외부 코드에서 Product의 clone을 통해 복제본을 얻을 수 있다.

2. Client

public class Client {
    public static void main(String[] args) {
        Product p1 = new Product("1", "Product1", "This is Product1");		
        Product copyp1 = p1.clone();
    }
}

깊은복사 얕은복사

  • 얕은복사: 얕은 복사는 객체를 복사할 때 내부의 데이터에 대한 참조를 공유하는 복사형태로 원본 객체에서 값을 변경하면 복사 객체의 값도 변경된다.
  • 깊은복사: 깊은 복사는 객체를 복사할 때 내부 데이터와 그 데이터가 참조하는 객체까지 복사한다. 얕은복사와 다르게 원본 객체에서 값을 변경해도 복사 객체의 값은 변하지 않는다.

JAVA: Cloneable

Cloneable은 JAVA에서 객체 복제를 가능하게 만드는 인터페이스이다. 인터페이스이므로 Cloneable를 상속 받는 객체는 clone()을 오버라이드 해야하고 구현을 해야한다.

clone()을 구현하지 않으면 CloneNotSupportedException가 발생할 수 있다.

profile
게임 개발자가 되고 싶은 한 소?년

0개의 댓글