日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

一起了解原型模式

發布時間:2023/11/29 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一起了解原型模式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原型模式

原型模式,用起來其實就是做clone操作,clone一個對象,越過構造器,在特定使用場景下增加效率。

UML

使用場景:

  • 類初始化需要消耗很多資源,比較耗時。
  • new方式非常繁瑣,還涉及到權限之類的。用clone就減少操作。
  • 一個對象需要提供給其他對象使用,而且各個使用都可能改到值,可以考慮用原型模式,做保護性拷貝。
  • 先說說原型模式主要的淺拷貝和深拷貝:

    淺拷貝:

    可被clone的對象:

    • 實現 Cloneable接口
    • 重寫clone方法
    • 先clone,再給參數賦值
    public class Document implements Cloneable {private String mText;private ArrayList<String> list = new ArrayList<>();public String getmText() {return mText;}public void setmText(String mText) {this.mText = mText;}@Overrideprotected Document clone() throws CloneNotSupportedException {Document document = (Document) super.clone();document.mText = this.mText;document.list = this.list;return document;} } 復制代碼

    深拷貝:

    對于上面ArrayList,它自身實現類cloneable接口的,所以它本身也是可以clone的,對于對象,賦值后,是指向同一個地址的,對于淺拷貝來說,如果改了list對象,那么原有的對象list也會被修改到。所以對于list對象,我們也需要拷貝一下,修改如下。

    public class Document implements Cloneable {private String mText;private ArrayList<String> list = new ArrayList<>();public String getmText() {return mText;}public void setmText(String mText) {this.mText = mText;}@Overrideprotected Document clone() throws CloneNotSupportedException {Document document = (Document) super.clone();document.mText = this.mText;document.list = (ArrayList<String>) this.list.clone();return document;} }復制代碼

    檢驗

    首先:對于淺拷貝

    • 我們用下面一段代碼來做檢驗:
    Document document = new Document();document.setmText("11111100000");document.getList().add("00");System.out.println("內容原始:" + document.toString());Document document1 = document.clone();document1.setmText("111111");document1.getList().add("111");System.out.println("內容修改:" + document1.toString());System.out.println("內容原始:" + document.toString());復制代碼
    • 輸出:
    內容原始:Document{mText='11111100000', list=[00]} 內容修改:Document{mText='111111', list=[00, 111]} 內容原始:Document{mText='11111100000', list=[00, 111]} 復制代碼

    這里很明顯的能看到,我們改了String類型,也改了list對象。但是輸出后,原始的String類型的text沒變,但是list卻被改變了。 這是為什么呢?

    原因其實是: String類型是不可變類型,所以我們不推薦在for循環中使用+號來拼接一樣,因為每+一次就會創建一塊內存來裝。同理,這里的雖然拷貝了string類型,但是第二個對象修改的時候,string的text是指向了新的地址而不是把原地址數據給改了,所以原對象的text并沒被改。但list就不一樣了,改的是原對象地址的數據 所以我們才會需要深拷貝。

    然后我們再檢驗一次深拷貝的:

    輸出內容:

    內容原始:Document{mText='11111100000', list=[00]} 內容修改:Document{mText='111111', list=[00, 111]} 內容原始:Document{mText='11111100000', list=[00]}復制代碼

    我們使用深拷貝的時候,將對象list也clone了,就沒有指向的不再是原有地址了,所以改動也就影響不到原來數據咯。

    另外:實現Cloneable接口只是一種方式。要實現clone也不一定非要實現這個接口(使用Object來重寫clone方法的話一定要實現,不然會拋出異常)。

    如果使用new的方式并不耗資源等,clone的時候我們傳入自己,用new的效率或許會更高:

    public Document(Document document) {this.mText = document.getmText();this.list = document.getList();}@Overridepublic Document clone() throws CloneNotSupportedException {Document document = new Document(this);return document;} 復制代碼

    總結:原型模式在copy資源非常方便,當然拷貝不一定比new快,所以需要評估測試再考慮是否不用new

    轉載于:https://juejin.im/post/5b9893f9f265da0aa528f351

    總結

    以上是生活随笔為你收集整理的一起了解原型模式的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。