设计模式五: 原型模式(Prototype)
簡介
原型模式是屬于創建型模式的一種,是通過拷貝原型對象來創建新的對象.
萬能的Java超類Object提供了clone()方法來實現對象的拷貝.
可以在以下場景中使用原型模式:
意圖
使用原型實例指定要創建的對象類型,并通過拷貝這個原型來創建新對象。
類圖
實現
一. 淺拷貝和深拷貝的概念
Object.clone()方法實現的是對象的淺拷貝, 所謂淺拷貝就是當對象中有復雜引用類型的域變量時, 只拷貝該域變量的引用而不是內容, 當有任一方法修改域變量的狀態時會同時影響原型對象及拷貝對象, 實際上他們共用了同一個堆內存. 深拷貝創建的對象即是對原對象的完全拷貝,對任一對象的操作不會影響其他對象的狀態.
java中提供了Cloneable接口, 約定實現接口Cloneable且重寫Object.clone()方法的類可以用來拷貝自身. Cloneable是一個標記接口, 其中沒有定義任何方法.
二. 下面的代碼演示了使用clone()方法實現的深拷貝,這種方式更適合用于比較簡單的對象,否則clone()方法的實現可能會變得異常復雜.
import lombok.AllArgsConstructor; import lombok.Data;@Data @AllArgsConstructor public class CarProperty implements Cloneable {private String power;private double maxSpeed;private double oilPerKm;public Object clone(){Object obj = null;try {obj = super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}return obj;} } import lombok.AllArgsConstructor; import lombok.Data;@Data @AllArgsConstructor public class Car implements Cloneable {private String brand;private double price;private CarProperty carProperty;/*** 深拷貝在此實現,對于復雜的應用類型, 這里的代碼可能會相當復雜,如果類有修改(新增成員變量等),這里也需要相應修改* @return*/public Object clone(){Object car = null;try {car = super.clone();CarProperty carPropertyClone = (CarProperty)this.getCarProperty().clone();((Car)car).setCarProperty(carPropertyClone);} catch (CloneNotSupportedException e) {e.printStackTrace();}return car;}public static void main(String[] args) {CarProperty carProperty = new CarProperty("8匹",250,30);Car car= new Car("BMW",200,carProperty);Car copy = (Car) car.clone();System.out.println("copy最大速度為: "+copy.getCarProperty().getMaxSpeed());System.out.println("原型最大速度為: "+car.getCarProperty().getMaxSpeed());car.getCarProperty().setMaxSpeed(360);System.out.println("copy最大速度為: "+copy.getCarProperty().getMaxSpeed());System.out.println("原型最大速度為: "+car.getCarProperty().getMaxSpeed());}}三. 深拷貝的其他實現方式: 除了上面的方法,還可以使用反射機制創建對象的深拷貝, 另外一種更簡單的方式是使用序列化;
下面的代碼使用序列化方式實現對象的深拷貝,需實現Serializable接口.
總結
優點: 1. 如果對象創建比較復雜, 可以簡化創建過程, 提高效率;2. 可以保留對象狀態;
缺點: 對于clone()方式,如果類有修改則需要修改clone()的實現,不符合開閉原則; 復雜對象的clone邏輯可能較復雜;
JDK
java.lang.Object#clone()
總結
以上是生活随笔為你收集整理的设计模式五: 原型模式(Prototype)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 百度地图滚轮缩放,所在点偏移问题
- 下一篇: WPF性能调试系列 – 内存监测