淺析設計模式(八)——創建型模式之Prototype(原型模式)
阿新 • • 發佈:2018-08-08
ref rri head 創建型模式 obj www str 操作 接口
原型模式Prototype
本文的內容:
- 一、原型模式的定義
-
二、原型模式的參與者及其角色
-
三、原型模式的類圖
-
四、原型模式的示例
-
五、參考
一、原型模式的定義
定義:用原型實例指定創建對象的實例,並且通過拷貝這些原型創建新的對象。
使用現有的對象,生成一個完全一樣的拷貝(副本,內部屬性值一樣,而內存地址不一樣),但是這個拷貝和原對象不共用任何內部屬性元素,即實現了對象的深度克隆。這個“拷貝”的精確含義取決於該對象的類,一般含義是:
- 對任何的對象x,都有:x.clone()!=x。換言之,克隆對象與原對象不是同一個對象。
- 對任何的對象x,都有:x.clone().getClass() == x.getClass(),換言之,克隆對象與原對象的類型一樣。
- 如果對象x的equals()方法定義其恰當的話,那麽x.clone().equals(x)應當成立的。
二、原型模式的參與者及其角色
1、Prototype
- 聲明一個克隆自身的接口。
2、ConcretePrototype
- 實現一個克隆自身的操作。
3、Client
- 讓一個原型克隆自身從而創建一個新的對象。
三、原型模式的類圖
四、原型模式的示例
Java中可以使用以下幾種方式進行對象的深度克隆:
- 實現Cloneable接口,並重寫Object類中的clone()方法
- 實現序列化哈反序列化實現對象的深度克隆,實現Serializable接口或者Externalizable
下面使用Cloneable進行說明:
1、Prototype
使用Cloneable接口。
2、ConcretePrototype
實現一個克隆自身的操作,這裏是clone()方法,需要重新進行定義。
1 public class Name implements Cloneable{ 2 private String firstName; 3 private String lastName; 4 private Title title; 5 //Constructor with no arguments 6 public Name(){7 8 } 9 //Constructor with all arguments 10 public Name(String firstName, String lastName, Title title) { 11 super(); 12 this.firstName = firstName; 13 this.lastName = lastName; 14 this.title = title; 15 } 16 //all getters and setters 17 public String getFirstName() { 18 return firstName; 19 } 20 public void setFirstName(String firstName) { 21 this.firstName = firstName; 22 } 23 public String getLastName() { 24 return lastName; 25 } 26 public void setLastName(String lastName) { 27 this.lastName = lastName; 28 } 29 30 public Title getTitle() { 31 return title; 32 } 33 public void setTitle(Title title) { 34 this.title = title; 35 } 36 @Override 37 public Name clone() throws CloneNotSupportedException { 38 Name nameClone = (Name)super.clone(); 39 nameClone.setFirstName(new String(this.getFirstName())); 40 nameClone.setLastName(new String(this.getLastName())); 41 nameClone.setTitle(this.getTitle().clone()); 42 return nameClone; 43 } 44 45 }
這裏要註意的是,若屬性中有對象引用,同樣需要進行深度克隆,而該屬性也同樣需要實現Cloneable,重寫clone()方法。如上面的Title,如下:
1 public class Title implements Cloneable{ 2 private String pre; 3 private String title; 4 //Constructor with no arguments 5 public Title(){ 6 7 } 8 //Constructor with all arguments 9 public Title(String pre, String title) { 10 super(); 11 this.pre = pre; 12 this.title = title; 13 } 14 public String getPre() { 15 return pre; 16 } 17 public void setPre(String pre) { 18 this.pre = pre; 19 } 20 public String getTitle() { 21 return title; 22 } 23 public void setTitle(String title) { 24 this.title = title; 25 } 26 @Override 27 public Title clone() throws CloneNotSupportedException { 28 Title title = (Title)super.clone(); 29 title.setPre(new String(this.getPre())); 30 title.setTitle(new String(this.getTitle())); 31 return title; 32 } 33 }
3、Client
創建原型對象,然後進行克隆。main方法中進行,輸出結果均為false。
1 public class PrototypeTestApp { 2 public static void main(String[] args) throws CloneNotSupportedException { 3 Title title = new Title("Mr", "Doc"); 4 Name name = new Name("San", "Li", title); 5 6 Name nameClone = name.clone(); 7 8 System.out.println(nameClone.getFirstName() == name.getFirstName()); 9 System.out.println(nameClone.getLastName() == name.getLastName()); 10 System.out.println(nameClone.getTitle() == name.getTitle()); 11 System.out.println(nameClone.getTitle().getPre() == name.getTitle().getPre()); 12 System.out.println(nameClone.getTitle().getTitle() == name.getTitle().getTitle()); 13 } 14 }
五、參考
1、參考《Head First設計模式》和GoF《設計模式:可復用面向對象軟件的基礎》
2、代碼可參考【github傳送門】、UML類圖參考【github傳送門】
淺析設計模式(八)——創建型模式之Prototype(原型模式)