怎麼借鑒開源代碼來打造一些自身面對的問題解決方案?也許有一些Demo來進行回答演示或許更為貼近地氣些。這裡打算寫一些玩轉源碼為主題的文字來實踐的回答,最近在看P3C的一些源碼,那就從這開始吧。 ...
JAVA設計模式-原型模式
介紹
原型模式是一種創建型模式,用於創建重覆的對象,並且保證性能。原型模式創建的對象是由原型對象自身創建的,是原型對象的一個克隆,和原型對象具有相同的結構和相同的值。
適用場景
- 創建對象時我們不僅僅需要創建一個新的對象,可能我們還需要對象創建出來裡面的值和某一個對象也要完全一致,原型模式可以保證結構和值都相同。
- 創建對象時我們希望對創建出來的對象的修改不影響到原來的對象,可能通過原型模式進行創建,進行深度克隆。
- 創建對象時,如果對象是個複雜對象,裡面又包含了其他的複雜對象,我們希望創建的對象和原有對象保持一致,傳統模式new會非常麻煩,還需要考慮到裡面其他的複雜對象,這時候可以使用原型模式進行創建。
參與者
- Prototype: 抽象原型類,是一個抽象類或者介面,並且聲明一個克隆自身的介面。
- ConcretePrototype: 具體的原型類,需要實現抽象原型類裡面的介面,在克隆自身的介面裡面返回自己的一個克隆對象。
- Client: 客戶端類,作用是讓原型克隆自身來創建新的對象。
簡單示例
Prototype類
/**
* All rights Reserved, Designed By monkey.blog.xpyvip.top
*
* @version V1.0
* @Package com.xpyvip.designpattern.prototype
* @Description: 抽象原型類
* @Author: xpy
* @Date: Created in 2022年09月23日 2:58 下午
*/
public interface Prototype {
/**
* 克隆自身的介面
* @return
*/
public Prototype clone();
public String getName();
public void setName(String name);
}
ConcretePrototype類
/**
* All rights Reserved, Designed By monkey.blog.xpyvip.top
*
* @version V1.0
* @Package com.xpyvip.designpattern.prototype
* @Description: 具體原型類
* @Author: xpy
* @Date: Created in 2022年09月22日 10:41 上午
*/
public class ConcreteProtype implements Prototype{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public Prototype clone() {
ConcreteProtype concreteProtype = new ConcreteProtype();
concreteProtype.setName(this.name);
return concreteProtype;
}
}
Client類
/**
* All rights Reserved, Designed By monkey.blog.xpyvip.top
*
* @version V1.0
* @Package com.xpyvip.designpattern.prototype
* @Description: 測試類
* @Author: xpy
* @Date: Created in 2022年09月22日 10:37 上午
*/
public class Client {
public static void main(String[] args) {
Prototype prototype = new ConcreteProtype();
prototype.setName("測試1");
Prototype prototypeClone = prototype.clone();
System.out.println(prototype.getName());
System.out.println(prototypeClone.getName());
}
}
第二種寫法
Java中所有類都是Object的子類,在Object類中提供了clone()方法,但是需要實現Cloneable介面,否則會拋出CloneNotSupportedException異常。
PrototypeTest類
/**
* All rights Reserved, Designed By monkey.blog.xpyvip.top
*
* @version V1.0
* @Package com.xpyvip.designpattern.prototype
* @Description: 實現Cloneable介面
* @Author: xpy
* @Date: Created in 2022年09月23日 4:28 下午
*/
public class PrototypeTest implements Cloneable{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
protected Object clone() {
try{
return super.clone();
} catch (Exception e){
e.printStackTrace();
return null;
}
}
}
ClientTest類
/**
* All rights Reserved, Designed By monkey.blog.xpyvip.top
*
* @version V1.0
* @Package com.xpyvip.designpattern.prototype
* @Description: 客戶端測試類
* @Author: xpy
* @Date: Created in 2022年09月23日 4:30 下午
*/
public class ClientTest {
public static void main(String[] args) {
PrototypeTest prototypeTest = new PrototypeTest();
prototypeTest.setName("測試1");
PrototypeTest prototypeTestClone = (PrototypeTest) prototypeTest.clone();
System.out.println(prototypeTest.getName());
System.out.println(prototypeTestClone.getName());
}
}
擴展
淺拷貝(淺度克隆)
淺拷貝只複製值,不複製引用的對象。
- 基本數據類型,淺拷貝會將值傳遞給新的對象。
- 引用數據類型,例如數組,類對象,淺拷貝會將數組、類對象的引用值,也就是存儲的記憶體地址拷貝一份給新的對象,實際上兩個對象指向的都是同一塊記憶體空間,一個對象的修改會影響到另一個對象。
- 預設的clone方法是淺拷貝,super.clone()
深拷貝(深度克隆)
深拷貝會重新申請新的記憶體空間。
- 基本數據類型,深拷貝會克隆值給新的對象。
- 引用數據類型,深拷貝會重新申請新的記憶體空間,將原有對象指向的記憶體地址裡面的數據全部拷貝到新的記憶體空間中。新對象指向的是新分配的記憶體空間的記憶體地址。新對象的修改不會影響到其他對象。
- 上述的clone方式是淺拷貝,需要重寫預設的clone方法。
關註微信公眾號「平哥技術站」, 每日更新,在手機上閱讀所有教程,隨時隨地都能學習。
原文鏈接:https://monkey.blog.xpyvip.top/archives/java-she-ji-mo-shi---yuan-xing-mo-shi