프로그래밍/디자인패턴

디자인 패턴 - Prototype (Creational Pattern)

aiemag 2021. 2. 28. 20:37
반응형

Creational Pattern인 Prototype Pattern에 대해 정리합니다.

 

제국을 습격하기 위해서 대량의 clone을 생성해 봅시다:)

 


Definition

Prototype은 instance로 부터 별도의 instance를 만드는 패턴입니다.

 

 


Class Diagram

 

 

 


Sample Case

다음은 Prototype 패턴을 적용한 시나리오입니다.

 

Scenario

우리의 요리사(Cooker)는 호도과자 전문점을 차렸습니다.

 

다행히 아주 장사가 잘 되어 언제 주문이 들어올지 모르기 때문에 미리 호도과자 포장을 해두려고 합니다.

 

호도과자 개수에 따라 포장지를 다르게 싸두기 위한 틀을 만들어 놓고,(prepare())

 

주문이 들어오는 즉시, 틀로부터 호도과자를 빨리 만들어 내어(create()), 구매자의 정보를 입력한 뒤(setBuyer()), 하나씩 전달(send())하게 됩니다.

 

호도과자를 만들어 낼 때(create()) 호도과자는 같은 틀에서 나오지만, 세상에서 유일한 것이 되어야 합니다.

 

Class Diagram

Cooker class 로부터 WalnutCake의 틀을 미리 저장해 두고, 필요 시, 잽싸게 만들어서(create()) 판매하게 됩니다.

 

WalnutCake는 Cloneable 를 상속받아 clone()을 이용하여 유일한 객체를 만들 수 있습니다.

Code

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import framework.Cooker;
import framework.Product;
import framework.WalnutCake;
 
public class Main {
 
    public static void main(String[] args) {
        Cooker cooker = new Cooker();
        WalnutCake style1 = new WalnutCake('*'5);
        WalnutCake style2 = new WalnutCake('#'10);
        
        cooker.prepare("style1", style1);
        cooker.prepare("style2", style2);
        
        Product p1 = cooker.create("style1");
        p1.setBuyer("Sam");
                
        Product p2 = cooker.create("style2");
        p2.setBuyer("John");
        
        Product p3 = cooker.create("style2");
        p3.setBuyer("Mike");
        
        p1.send();
        p2.send();
        p3.send();
    }
}
 
cs

 

1
2
3
4
5
6
7
8
package framework;
 
public interface Product extends Cloneable{
    public abstract void setBuyer(String buyer);
    public abstract void send();
    public abstract Product createClone();
}
 
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package framework;
 
public class WalnutCake implements Product{
    private char pattern;
    private String buyer = "None";
    private int walnutCount = 0;
    
    public WalnutCake(char pattern, int walnutCount) {
        this.pattern = pattern;
        this.walnutCount = walnutCount;
    }
    
    public void setBuyer(String buyer) {
        this.buyer = buyer;
    }
    
    public void send() {
        System.out.println("To : "+this.buyer);
        
        int length = walnutCount + 4;
        for(int i=0 ; i<length ; i++) {
            System.out.print(pattern);
        }
        System.out.println("");
        
        System.out.print(pattern + " ");
        for(int i=0 ; i<walnutCount ; i++) {
            System.out.print("@");
        }
        System.out.println(" " + pattern);        
        
        for(int i=0 ; i<length ; i++) {
            System.out.print(pattern);
        }
        System.out.println("\n");
    }
    
    public Product createClone() {
        Product p = null;
        try {
            p = (Product)clone();
        }catch(CloneNotSupportedException e) {
            e.printStackTrace();
        }
        
        return p;
    }
}
 
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package framework;
 
import java.util.HashMap;
 
public class Cooker {
    private HashMap slot = new HashMap();
    
    public void prepare(String protoName, Product proto) {
        slot.put(protoName, proto);
    }
    
    public Product create(String protoName) {
        Product p = (Product)slot.get(protoName);
        
        return p.createClone();
    }
}
cs

 

 

실행 결과

반응형