java設計模式4——原型模式
1、寫在前面
本節內容與C++語言的復制建構式、淺拷貝、深拷貝極為相似,因此建議學習者可以先了解C++的該部分的相關知識,或者學習完本節內容后,也去了解C++的相應內容,進行比對學習,
2、原型模式介紹
原型模式(Prototype Pattern)是用于創建重復的物件,同時又能保證性能,這種型別的設計模式屬于創建型模式,它提供了一種創建物件的最佳方式,
這種模式是實作了一個原型介面,該介面用于創建當前物件的克隆,當直接創建物件的代價比較大時,則采用這種模式,例如,一個物件需要在一個高代價的資料庫操作之后被創建,我們可以快取該物件,在下一個請求時回傳它的克隆,在需要的時候更新資料庫,以此來減少資料庫呼叫,
3、java實作克隆的核心
1、實作一個介面(Cloneable)
2、重寫一個方法(clone())
clone()方法的原始碼分析
protected native Object clone() throws CloneNotSupportedException;
由方法宣告的放回值型別=>native,可知該方法實際上是一個C++封裝好的方法,由java來進行呼叫,相當于C++語言的復制建構式,但是又有所區別,
4、第一種原型模式實作(淺拷貝)
4.1、建立視頻的原型類
package com.xgp.company.創建型模式.第四種_原型模式.demo1;
import java.util.Date;
/**
* 1、實作一個介面
* 2、重寫一個方法
*/
//視頻原型類
public class Video implements Cloneable {
private String name;
private Date createTime;
/**
* 重寫克隆方法
* @return
* @throws CloneNotSupportedException
*/
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public Video() {
}
public Video(String name, Date createTime) {
this.name = name;
this.createTime = createTime;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
@Override
public String toString() {
return "Video{" +
"name='" + name + '\'' +
", createTime=" + createTime +
'}';
}
}
4.2、建立復制的客戶端類
package com.xgp.company.創建型模式.第四種_原型模式.demo1;
import java.util.Date;
/**
* 客戶端:克隆
*/
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
//原型物件
Video v1 = new Video("狂神說java", new Date());
System.out.println("v1 = " + v1);
System.out.println("v1 = " + v1.hashCode());
System.out.println("========================");
//v1 克隆 v2
Video v2 = (Video) v1.clone();
System.out.println("v2 = " + v2);
System.out.println("v2 = " + v2.hashCode());
}
}
運行結果:
v1 = Video{name='狂神說java', createTime=Fri Feb 14 10:26:57 CST 2020}
v1 = 1836019240
========================
v2 = Video{name='狂神說java', createTime=Fri Feb 14 10:26:57 CST 2020}
v2 = 325040804
5、弊端
5.1、揭露弊端的代碼
/**
* 演示淺克隆弊端
* @param args
* @throws CloneNotSupportedException
*/
public static void main(String[] args) throws CloneNotSupportedException {
//原型物件
Date date = new Date();
Video v1 = new Video("狂神說java", date);
System.out.println("v1 = " + v1);
System.out.println("v1 = " + v1.hashCode());
//v1 克隆 v2
Video v2 = (Video) v1.clone();
System.out.println("v2 = " + v2);
System.out.println("v2 = " + v2.hashCode());
System.out.println("========================");
date.setTime(22222222);
System.out.println("v1 = " + v1);
System.out.println("v1 = " + v1.hashCode());
//v1 克隆 v2
System.out.println("v2 = " + v2);
System.out.println("v2 = " + v2.hashCode());
}
5.2、弊端代碼的運行結果
v1 = Video{name='狂神說java', createTime=Fri Feb 14 10:29:02 CST 2020}
v1 = 1836019240
v2 = Video{name='狂神說java', createTime=Fri Feb 14 10:29:02 CST 2020}
v2 = 325040804
========================
v1 = Video{name='狂神說java', createTime=Thu Jan 01 14:10:22 CST 1970}
v1 = 1836019240
v2 = Video{name='狂神說java', createTime=Thu Jan 01 14:10:22 CST 1970}
v2 = 325040804
5.3、弊端分析
從運行結果可以看出,當改變一個被v1,v2都參考的時間物件時,兩者都發生了改變,沒有將參考的物件進行復制,因此稱之為淺拷貝,
5.4、模型圖如下:

通過上面的模型圖可以看到,被參考的物件還是只有一份,因此存在很大的弊端,在C++中,如果存在這種參考關閉,當程式員兩次洗掉物件時,會出現第二次刪物件時發生異常的情況,雖然在java語言中,有著gc機制,不需要程式員手動的去釋放物件,不會出現重復洗掉的錯誤,但是,當被參考的物件發生改變時,很有可能會發生資料上的不正確,
6、改進(深拷貝模式)
6.1、我們期望想要改進后的模型圖如下:被參考的物件也復制了一份,互不干擾,

6.2、實作方式:改造重寫的克隆方法
@Override
protected Object clone() throws CloneNotSupportedException {
/**
* 改造克隆方法,進行生克隆
*/
Object obj = super.clone();
Video v = (Video) obj;
//將物件的屬性進行克隆
v.createTime = (Date) this.createTime.clone();
return obj;
}
6.3、此時的運行結果為:
v1 = Video{name='狂神說java', createTime=Fri Feb 14 10:37:33 CST 2020}
v1 = 1836019240
v2 = Video{name='狂神說java', createTime=Fri Feb 14 10:37:33 CST 2020}
v2 = 325040804
========================
v1 = Video{name='狂神說java', createTime=Thu Jan 01 14:10:22 CST 1970}
v1 = 1836019240
v2 = Video{name='狂神說java', createTime=Fri Feb 14 10:37:33 CST 2020}
v2 = 325040804
6.4、當原型參考的對像改變時,復制的物件并不發生改變,被參考的物件被復制了兩份,因此稱之為深拷貝,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/26087.html
標籤:設計模式
上一篇:java設計模式3——建造者模式
下一篇:設計模式——簡單工廠模式
