728x90
프로토타입 패턴(Prototype Pattern)은 객체를 직접 생성하는 대신, 기존 객체를 복제(clone) 하여 새로운 객체를 생성하는 디자인 패턴입니다. 이 패턴은 객체 생성 비용이 크거나, 생성 과정이 복잡할 때 유용합니다.
프로토타입 패턴의 특징
- 복제: 새로운 객체를 생성할 때 기존 객체를 복제하여 사용합니다.
- 성능 향상: 객체 생성 비용을 줄이고, 복잡한 초기화 과정을 단순화합니다.
- 유연성: 런타임에 객체를 복제하고 수정할 수 있어 동적인 객체 관리가 가능합니다.
사용 시점
- 객체 생성 비용이 클 때 (예: 데이터베이스 조회, 네트워크 호출 등).
- 객체의 구조가 복잡하고 생성 로직을 단순화하려고 할 때.
- 기존 객체를 재사용하면서 일부 속성만 변경하고 싶을 때.
자바에서 프로토타입 패턴 구현하기
자바에서 프로토타입 패턴은 보통 Cloneable 인터페이스와 clone() 메서드를 사용하여 구현합니다. Cloneable 인터페이스는 객체가 복제 가능하다는 표시(interface marker) 역할을 합니다.
1. 기본 구현
public class Prototype implements Cloneable {
private String name;
private int value;
public Prototype(String name, int value) {
this.name = name;
this.value = value;
}
// Getter and Setter
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
// clone() 메서드 재정의
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "Prototype{name='" + name + '\'' + ", value=" + value + '}';
}
}
2. 사용 예제
public class PrototypePatternDemo {
public static void main(String[] args) {
try {
// 원본 객체 생성
Prototype original = new Prototype("Original", 100);
System.out.println("Original: " + original);
// 복제 객체 생성
Prototype clone = (Prototype) original.clone();
clone.setName("Clone"); // 복제 객체의 속성 변경
System.out.println("Clone: " + clone);
System.out.println("Original after clone modification: " + original);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
출력:
Original: Prototype{name='Original', value=100}
Clone: Prototype{name='Clone', value=100}
Original after clone modification: Prototype{name='Original', value=100}
깊은 복사(Deep Copy)와 얕은 복사(Shallow Copy)
clone() 메서드로 생성된 객체는 기본적으로 얕은 복사(Shallow Copy)를 수행합니다. 얕은 복사는 객체의 필드 값만 복사하며, 참조형 변수는 같은 객체를 참조합니다. 반면, 깊은 복사(Deep Copy)는 참조된 객체까지 모두 새로 생성합니다.
얕은 복사의 문제점
만약 객체가 참조형 필드를 포함하고 있다면, 얕은 복사는 다음과 같은 문제가 발생할 수 있습니다.
public class ShallowPrototype implements Cloneable {
private String[] data;
public ShallowPrototype(String[] data) {
this.data = data;
}
public String[] getData() {
return data;
}
public void setData(String[] data) {
this.data = data;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class ShallowCopyDemo {
public static void main(String[] args) throws CloneNotSupportedException {
String[] data = {"A", "B", "C"};
ShallowPrototype original = new ShallowPrototype(data);
ShallowPrototype clone = (ShallowPrototype) original.clone();
clone.getData()[0] = "X"; // 복제 객체 수정
System.out.println("Original: " + String.join(", ", original.getData()));
System.out.println("Clone: " + String.join(", ", clone.getData()));
}
}
출력:
Original: X, B, C
Clone: X, B, C
깊은 복사 구현
깊은 복사를 위해서는 참조된 객체도 복제해야 합니다.
@Override
protected Object clone() throws CloneNotSupportedException {
ShallowPrototype deepCopy = (ShallowPrototype) super.clone();
deepCopy.data = data.clone();
return deepCopy;
}
프로토타입 패턴의 장단점
장점
- 객체 생성 비용 절감: 복잡한 객체 생성 과정을 단순화합니다.
- 유연성: 기존 객체를 기반으로 손쉽게 새로운 객체를 생성할 수 있습니다.
- 성능 향상: 객체를 복제하여 생성하므로 성능이 향상됩니다.
단점
- 복잡성 증가: 깊은 복사를 구현할 때 참조 객체가 많아질수록 복잡도가 증가합니다.
- Cloneable 인터페이스 한계: 자바의 Cloneable 인터페이스는 제한적이며, 사용 시 주의가 필요합니다.
결론
프로토타입 패턴은 객체 생성 비용을 줄이고, 복잡한 객체 생성 과정을 단순화하는 데 유용한 디자인 패턴입니다. 특히, 객체를 동적으로 생성하거나 기존 객체를 기반으로 수정해야 하는 상황에서 효과적입니다. 다만, 얕은 복사와 깊은 복사 문제를 이해하고 적절히 구현해야 합니다.
728x90
'Design Pattern with Java' 카테고리의 다른 글
5. 템플릿메소드 패턴(Template Method) (0) | 2025.01.15 |
---|---|
4. Builder 패턴(from effective-java) (0) | 2025.01.07 |
4. builder 패턴(gof) (0) | 2025.01.07 |
3.추상 팩토리 패턴(Abstract Factory Pattern) (0) | 2025.01.07 |
1. 싱글톤 패턴(Singleton Pattern) (0) | 2025.01.07 |