1. Prototype
- 복사해서 인스턴스를 만든다
- 종류가 너무 많아 클래스로 정리할 수 없는 경우
- 취급할 오브젝트 종류가 너무 많아서, 하나하나 다른 클래스로 만들면 소스 파일을 많이 작성해야 하는경우
- 클래스로부터 인스턴스 생성이 어려운 경우
- 생성하고 싶은 인스턴스가 복잡한 과정을 거쳐 만들어지는 것으로, 클래스로부터 만들기가 매우 어려운 경우
- 프레임워크와 생성하는 인스턴스를 분리하고 싶은 경우
- 인스턴스를 생성하는 프레임워크를 특정 클래스에 의존하지 않게 하고 싶은 경우
- 왜 복사를 하는가?
- 생성하는 과정이 어렵고 복잡하고 효율이 안좋아서 복사만하면 그 많은 과정과 자원을 아낄 수 있다.
- 하나의 객체만 사용하는 것과 복제를 사용하는 것 사이에는 중요한 차이
- 복제본을 만들면, 원본 객체와 복제본이 각각 독립적인 상태를 가질 수 있다.
- 하나의 객체만 사용하는 경우 : 하나의 객체를 여러 군데에서 공유해서 사용한다고 가정하면, 이 객체의 상태가 공유됩니다. 즉, 객체의 상태가 하나의 곳에서 변경되면, 그 객체를 사용하는 다른 모든 곳에서 상태 변화가 영향을 미치게 됩니다. 이 방식은 상태 변경을 중앙에서 제어할 수 있긴 하지만, 복잡한 시스템에서는 예기치 않은 부작용을 일으킬 수 있습니다.
- 복제된 객체를 사용하는 경우 : 프로토타입 패턴을 사용하면, 원본 객체를 복제하여 여러 개의 객체를 만들 수 있고, 이 복제된 객체들은 각각 독립적인 상태를 가질 수 있습니다. 즉, 하나의 객체를 복제하고, 각 복제본이 별도로 변경될 수 있기 때문에, 독립적인 작업을 각 객체가 수행할 수 있습니다.
- 종류가 너무 많아 클래스로 정리할 수 없는 경우
- 예제
- interface Product
package design.prototype.framework;
public interface Product extends Cloneable{
public abstract void use(String s); // 사용하기 위한 메서드
public abstract Product createCopy(); // 인스턴스를 복제하기 위한 메서드
}
- class Manager
package design.prototype.framework;
import java.util.HashMap;
import java.util.Map;
public class Manager {
private Map<String, Product> showcase = new HashMap<>();
// Product를 구현한 클래스를 매개 변수로 받을 수 있다.
public void register(String name, Product prototype) {
// key(strong message) value(upen)
// key(warning box) value(mbox)
// key(slash box) value(sbox)
showcase.put(name, prototype);
}
public Product create(String prototypeName) {
// Product p 에 upen, mbox, sbox를 대입
Product p = showcase.get(prototypeName);
// 복제본 반환
return p.createCopy();
}
}
- class MessageBox
package design.prototype;
import design.prototype.framework.Product;
public class MessageBox implements Product{
private char decochar;
public MessageBox(char decochar) {
this.decochar = decochar;
}
@Override
public void use(String s) {
int decolen = 1 + s.length() + 1;
for (int i = 0; i < decolen; i++) {
System.out.print(decochar);
}
System.out.println();
System.out.println(decochar+ s + decochar);
for (int i = 0; i < decolen; i++) {
System.out.print(decochar);
}
System.out.println();
}
@Override
public Product createCopy() {
Product p = null;
try{
p = (Product)clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return p;
}
}
- class UnderlinePen
package design.prototype;
import design.prototype.framework.Product;
public class UnderlinePen implements Product {
private char ulchar;
public UnderlinePen(char ulchar){
this.ulchar = ulchar;
}
@Override
public void use(String s){
int ulen = s.length();
System.out.println(s);
for(int i = 0; i < ulen; i++) {
System.out.print(ulchar);
}
System.out.println();
}
@Override
public Product createCopy() {
Product p = null;
try{
p = (Product)clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return p;
}
}
- Main
package design.prototype;
import design.prototype.framework.Manager;
import design.prototype.framework.Product;
public class Main {
public static void main(String[] args) {
// 준비
Manager manager = new Manager();
// interface Product를 구현한 하위 클래스들
UnderlinePen upen = new UnderlinePen('-');
MessageBox mbox = new MessageBox('*');
MessageBox sbox = new MessageBox('/');
upen.use("hello");
// 등록
manager.register("strong message", upen);
manager.register("warning box", mbox);
manager.register("slash box", sbox);
// 생성과 사용
Product p1 = manager.create("strong message");
p1.use("Hello, world.");
p1.use("hell");
Product p2 = manager.create("warning box");
p2.use("Hello, world.");
Product p3 = manager.create("slash box");
p3.use("Hello, world.");
}
}
'디자인 패턴' 카테고리의 다른 글
5. Strategy - 패스트캠퍼스 백엔드 부트캠프 3기 (1) | 2025.02.17 |
---|---|
4. Template Method - 패스트캠퍼스 백엔드 부트캠프 3기 (0) | 2025.02.11 |
2. Flyweight(추가예정) - 패스트캠퍼스 백엔드 부트캠프 3기 (0) | 2025.02.06 |
1. Singleton - 패스트캠퍼스 백엔드 부트캠프 3기 (2) | 2025.02.06 |