原型模式的使用場景

2021-09-23 23:50:05 字數 4247 閱讀 1007

(1)類初始化需要消化非常多的資源,這個資源包括資料、硬體資源等,通過原型拷貝避免這些消耗。

(2)通過new乙個物件需要非常繁瑣的資料準備或訪問許可權,可以使用原型模式。

(3)乙個物件需要提供給其他物件訪問,而且各個呼叫者可能需要修改其值,可以考慮使用原型模式拷貝多個物件供呼叫者使用,即保護性拷貝

**注:**通過實現cloneable介面的原型模式,在呼叫clone函式例項時比一定比new 操作要塊,只有new構造物件非常耗時或者成本較高時,通過clone方法才能得到效率上的提公升。因此在使用cloneable時需要考慮構建物件成本以及效率上的一些測試。

檔案類-worddocument

public class worddocument implements cloneable catch (clonenotsupportedexception e)

// return null;

// }

//深拷貝--建議使用

@override

protected worddocument clone() catch (clonenotsupportedexception e)

return null;

}public worddocument()

public string getmtext()

public void setmtext(string mtext)

public arraylist getmimages()

public void addimages(string img)

public void showdocument()

system.out.println("word content end");

}}

輸出類-client

public class client

}

總結

淺拷貝遇到的問題

說明 worddocument的clone方法只是簡單的進行淺拷貝,引用型別的新物件doc的mimage只是單純的指向了this.mimages的引用,並沒有重新構造mimages物件,然後將原始文件中的新增到新的mimages物件中,這樣導致doc中的mimages與原始檔案中的是同乙個物件,因此修改了其中乙個文件中的,另乙個文件也會受到影響.

解決方法:採用深拷貝 即–在拷貝物件時,對引用型的字段也要採用拷貝的形式,而不是單純的引用形式.

intent用於跳轉activity、啟動服務、發布廣播等功能,它是android系統各個元件之間的紐帶,也是元件之間傳遞資料的載體,正式intent的存在才使得android各個元件之間的耦合性很低。
發資訊操作

uri uri = uri.parse("smsto:13426074245");

intent intent = new intent(intent.action_sendto, uri);

intent.putextra("sms_body", "send content");

intent sendto = (intent) intent.clone();

startactivity(sendto);

上述**中構建了乙個發簡訊的intent物件,並設定了發簡訊的內容,通過原始intent的clone()方法構建乙個intent副本,在使用副本進行發簡訊操作。
原始碼

@override

public object clone()

/*** copy constructor.

*/public intent(intent o)

private intent(intent o, @copymode int copymode)

if (copymode != copy_mode_filter)

if (o.mselector != null)

if (copymode != copy_mode_history)

if (o.mclipdata != null)

} else

// also set "stripped" clip data when we ever log mclipdata in the (broadcast)

// history.}}

}

通過原始碼可以看到clone方法實際上在內部並沒有呼叫super.clone()方法來實現物件拷貝,而是呼叫了new intent(this)。這個在上文中提到過,使用clone 和new 需要根據構造物件的成本來決定,如果物件的構造成本比較高或者構造比較麻煩,那麼使用clone()函式效率較高,否則可以使用new 的形式。(這就和c++的拷貝建構函式完全一致),將原始物件作為建構函式的引數,然後在建構函式內將原始物件的資料逐個拷貝一遍。到此轉殖過程就完成了。

public class user

}

public class loginimpl implements login 

//登入成功呼叫 為了簡化,在初始化時就呼叫了

@override

public void longin()

}

public class loginsession 

public static loginsession getloginsession()

return loginsession;

}void setloginuser(user user)

public user getloinguser()

}

執行

new loginimpl();

system.out.println(loginsession.getloginsession().getloinguser().tostring());

user user = loginsession.getloginsession().getloinguser();

user.adress = new adress("name", "obname", "ssname");

system.out.println(loginsession.getloginsession().getloinguser().tostring());

輸出:user[aget=22,name=mr.******,phonenum=nulladress=adress[ city=北京,district=朝陽,street=四惠]]

user[aget=22,name=mr.******,phonenum=nulladress=adress[ city=name,district=obname,street=ssname]]

修改資料的引用是一樣的 即便沒有通過構造修改引數也會生效

使用原型模式clone出乙個備份使用,即便客戶端無意識修改了,對儲存引數的類也不會影響修改如下:

user修改

public class user implements cloneable catch (clonenotsupportedexception e)

return user;

}@override

public string tostring()

}

public class loginsession 

public static loginsession getloginsession()

return loginsession;

}void setloginuser(user user)

//使用clone函式

public user getloinguser()

}

優點:原型模式是在記憶體中二進位製流的拷貝,要比直接new 乙個物件效能好很多,特別是要在乙個迴圈體內產生大量的物件時,原型模式可以更好的體現其有點

缺點:它的優點也是缺點,直接在記憶體彙總拷貝,建構函式是不會執行的,在實際開發中,應該注意這個潛在的問題.優點是減少了約束,缺點也是減少了約束,需要再時機應用的時候考慮

參考–android原始碼設計模式解析與實戰

建立型模式 原型模式

使用原型例項指定建立物件的種類,並且通過轉殖這些原型建立新的物件 原理是將乙個原型物件傳給要發動建立的物件,該物件通過請求原型物件轉殖自己來建立過程 轉殖方法 public prototype clone jdk中為我們提供了轉殖的方法clone 從object繼承下來,乙個物件要實現轉殖,需要實現...

建立型模式 原型模式

原型 prototype 模式主要用於建立物件的轉殖,通常其最簡單的形式就是採用自定 clone 函式並 傳入物件引數以返回此物件的乙個副本,這在 python 實作上可使用內定 copy.cop y 或 copy.deepcopy 函式來達到此目的。當已有乙個物件但對此物件的某些部分會被變更卻又想...

原型模式 建立型模式

文章首發個人部落格 如果我們有乙個類 sheep 它裡面有兩個屬性,名稱 name 年齡 age 現在我們有乙個它的例項 s1 我們需要按照這個例項的屬性再去建立兩個物件。1 sheep data public class sheep 2 main public class main 原型模式 用原...