原型模式

📢 本文由 gemini-3-flash-preview 翻譯

Prototype Pattern 物件建立型模式

意圖

用原型執行個體指定建立物件的種類,並且透過複製這些原型建立新的物件

結構

image

其中:

  • Prototype 宣告一個複製自身的介面
  • ConcretePrototype 實作一個複製自身的操作
  • Client 讓一個原型複製自身從而建立一個新的物件

適用性

Prototype 模式適用於:

  • 當一個系統應該獨立於它的產品建立、構成和表示時
  • 當要實例化的類別是在執行期間指定時,例如,透過動態載入
  • 為了避免建立一個與產品類別階層平行的工廠類別階層時
  • 當一個類別的執行個體只能有幾個不同狀態組合中的一種時。建立對應數量的原型並複製它們,可能比每次用合適的狀態手動實例化該類別更方便一些

例子 1

 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
public class main{
    Product p1 = new Product(2023, 3.03);
    System.out.println(p1.getId() + " " + p1.getPrice());

    // Product p2 = new Product(2023, 3.03);
    Product p2 = (Product) p1.Clone();
    System.out.println(p2.getId() + " " + p2.getPrice());
}

interface Prototype{
    public Object Clone();
}

class Product implements Prototype{
    private int id;
    private double price;

    public Product(){}
    public Product(int id, double price){
        this.id = id;
        this.price = price;
    }

    public int getId(){
        return this.id;
    }
    public double getPrice(){
        return this.price;
    }

    public void setId(int id){
        this.id = id;
    }
    public void setPrice(double price){
        this.price = price;
    }

    @Override
    public Object Clone(){
        Product object = new Product();
        object.id = this.id;
        object.price = this.price;
        return object;
    }
}

例子 2 (使用官方介面)

 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
public class main{
    Product p1 = new Product(2023, 3.03);
    System.out.println(p1.getId() + " " + p1.getPrice());

    // Product p2 = new Product(2023, 3.03);
    Product p2 = (Product) p1.clone();
    System.out.println(p2.getId() + " " + p2.getPrice());
}

// 去除
// interface Prototype{
//     public Object Clone();
// }

// 實作介面
class Product implements Cloneable{
    private int id;
    private double price;

    public Product(){}
    public Product(int id, double price){
        this.id = id;
        this.price = price;
    }

    public int getId(){
        return this.id;
    }
    public double getPrice(){
        return this.price;
    }

    public void setId(int id){
        this.id = id;
    }
    public void setPrice(double price){
        this.price = price;
    }
    
    // 覆寫方法
    @Override
    public Object clone(){
        return super.clone();
    }
}