(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 原型模式 用原...