Hello

[디자인 패턴] - Prototype

by 볼빵빵오춘기

Prototype 패턴

  • Prototype 패턴은 기존 객체를 복사하여 새로운 객체를 생성하는 방식의 디자인 패턴이다.
  • 객체를 생성할 때 new 키워드로 직접 생성하는 것이 아니라, 기존 객체를 복제(clone)하여 생성하는 것이 특징이다.

 

예제 코드

// 1. Prototype 인터페이스
interface Prototype extends Cloneable {
    Prototype clone();  // 복제 메서드
}

// 2. 구체적인 Prototype 클래스
class ConcretePrototype implements Prototype {
    private String name;

    public ConcretePrototype(String name) {
        this.name = name;
    }

    @Override
    public Prototype clone() {
        try {
            return (Prototype) super.clone(); // 얕은 복사
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException("복제 실패", e);
        }
    }

    public void showInfo() {
        System.out.println("Prototype name: " + name);
    }
}

// 3. 사용 예시
public class PrototypeExample {
    public static void main(String[] args) {
        ConcretePrototype prototype1 = new ConcretePrototype("Original");
        prototype1.showInfo();

        // prototype1을 복제하여 새로운 객체 생성
        ConcretePrototype prototype2 = (ConcretePrototype) prototype1.clone();
        prototype2.showInfo();  // "Original"과 같은 값을 가진 객체 생성됨
    }
}

 

Prototype 패턴의 장점

객체 생성 비용 절감

 

  • 새로운 객체를 생성하는 것보다 기존 객체를 복제(clone) 하는 것이 더 빠르고 효율적이다.
  • 특히 복잡한 객체를 생성하는 비용이 클 때 유용하다.

 

 

캡슐화 유지

  • clone() 메서드를 사용하면 객체 생성에 대한 내부 로직을 외부에서 몰라도 된다.
  • 복잡한 초기화 과정을 감출 수 있다.

 

객체의 동적 생성 가능

  • 런타임에서 객체를 복사하여 새로운 인스턴스를 생성할 수 있다.
  • 팩토리 메서드 패턴과 다르게 새로운 서브클래스를 만들 필요 없이 동적으로 객체를 생성할 수 있다.

 

구체적인 클래스에 의존하지 않는다.

 

  • 객체의 타입을 명확히 알 필요 없이 복사해서 사용할 수 있다.
  • 팩토리 메서드 패턴처럼 하위 클래스에서 객체 생성을 제어하는 것이 아니라, 기존 객체를 복제하여 유연하게 생성 가능하다.

 

 

Prototype 패턴의 단점

객체 복사(clone) 시 깊은 복사(Deep Copy) vs 얕은 복사(Shallow Copy) 문제

 

  • clone() 메서드를 사용할 때 기본적으로 얕은 복사(Shallow Copy) 가 수행된다.
  • 객체 내에 참조 타입(배열, 리스트, 다른 객체)이 포함되어 있다면, 해당 참조 값만 복사되므로 원본이 변경될 경우 복제 객체에도 영향을 준다. 이를 방지하려면 깊은 복사(Deep Copy)를 직접 구현해야 한다.

 

객체 복제가 복잡할 수 있다.

 

  • 복제할 객체가 복잡한 구조를 가지거나, 다른 객체와 관계(Composition, Aggregation) 를 맺고 있다면 복제 과정이 어려울 수 있다.
  • 복사할 객체가 많거나, 상속 관계가 깊으면 유지보수가 어려워진다.

 

객체의 복제 가능 여부를 보장해야 한다.

  • Cloneable 인터페이스를 구현해야 clone() 메서드를 사용할 수 있다.
  • 복제 과정에서 예외(CloneNotSupportedException)가 발생할 수도 있다.

 

Prototype 패턴을 언제 사용할까?

객체 생성 비용이 클 때

 

복잡한 초기화 과정이 필요한 객체를 반복적으로 생성해야 하는 경우(예: 대량 데이터 처리, 게임에서 캐릭터 복제 등).

ex) 데이터베이스에서 조회한 결과를 캐싱 후 복제하여 사용.

 

객체의 상태가 유사하게 유지되어야 할 때

 

기본 틀을 유지하면서 약간만 수정해서 사용할 경우.

ex) 게임에서 기본 캐릭터를 만든 후, 다양한 스킨과 아이템을 장착한 변형 캐릭터를 만들 때.

 

클래스 수를 줄이고 싶을 때

 

 

팩토리 패턴처럼 하위 클래스를 많이 생성하는 대신 기존 객체를 복사하여 변형하는 방식이 더 적합한 경우.

 

객체의 구조가 복잡하여 생성이 어려운 경우

객체 내부에 다양한 필드나 참조 객체가 포함되어 있어서 직접 생성하는 것이 어렵거나 비효율적인 경우.

 

Prototype 패턴 vs Factory Method 패턴 차이

  Prototype 패턴 Factory Method 패턴
객체 생성 방식 기존 객체를 복제(클론) 팩토리 메서드를 통해 객체 생성
주요 목적 객체 복제(성능 최적화) 객체 생성 캡슐화
유연성 런타임에서 새로운 객체 쉽게 생성 가능 새로운 객체를 만들려면 서브클래스 확장이 필요
사용 객체 생성 비용이 클 때 (캐싱, 복잡한 초기화) 객체 생성을 캡슐화하고, 구체적인 클래스의 의존성을 줄일 때

 

정리하자면

  • Prototype 패턴은 객체를 새로 생성하는 비용을 줄이고, 기존 객체를 빠르게 복사하여 사용할 때 유용하다.
  • But 깊은 복사/얕은 복사 문제를 고려해야 하며, 복잡한 객체 구조에서는 관리가 어려울 수 있다.

블로그의 정보

Hello 춘기's world

볼빵빵오춘기

활동하기