用原型實例指定創建對象的種類,並且通過拷貝這些原型創建新的對象。
原型模式---Prototype,是指創建新的對象的時候,根據一個現有的原型來創建。
我們舉個例子:如果我們已經有了一個String[]數組,想要再創建一個一摸一樣的String[]數組,怎么寫?
實際上創建的過程很簡單,就是把現有的數組的元素復制到新的數組。如果我們把這個創建的過程封裝一下,就成了原型模式,用代碼實現如下:
// 原型: String[] original = { "Apple", "Pear", "Banana" }; // 新對象: String[] copy = Arrays.copyOf(original, original.length);
對於普通類,我們如何實現原型拷貝?Java的Obejct提供了一個clone()方法,它的意圖計時復制一個新的對象出來,我們需要實現一個Cloneable接口來標識一個對象是“可復制”的:
public class Student implements Cloneable { private int id; private String name; private int score; // 復制新對象並返回: public Object clone() { Student std = new Student(); std.id = this.id; std.name = this.name; std.score = this.score; return std; } }
使用的時候,是因為clone()方法的簽名是定義在Obejct中,返回的類型也是Obejct的我,但是可以使用后一個泛型規定了返回的類型,就不需要去強制類型轉換,強制轉換的時候比較麻煩。
Student std1 = new Student(); std1.setId(123); std1.setName("Bob"); std1.setScore(88); // 復制新對象: Student std2 = (Student) std1.clone(); System.out.println(std1); System.out.println(std2); System.out.println(std1 == std2); // false
還可以自己定義一個方法,在方法內部實現創建一個新的對象並且返回(復制完現有的數據以后返回)。
public class Student { private int id; private String name; private int score; public Student copy() { Student std = new Student(); std.id = this.id; std.name = this.name; std.score = this.score; return std; } }
原型模式應用不是很廣泛,因為很多實例會持有類似文件,Socket這樣的資源,而這樣的資源是無法復制給另一個對象共享的,只有存儲簡單類型的“值”對象可以復制。