Head First设计模式之原型模式
一、定義
用原型實例指定創建對象的種類,并且通過拷貝這些原型創建新的對象。
原型模式是一種比較簡單的模式,也非常容易理解,實現一個接口,重寫一個方法即完成了原型模式。在實際應用中,原型模式很少單獨出現。經常與其他模式混用,他的原型類Prototype也常用抽象類來替代。
二、結構圖
?
原型模式主要用于對象的復制,它的核心是就是類圖中的原型類Prototype。Prototype類需要具備以下兩個條件:
- 實現Cloneable接口。在java語言有一個Cloneable接口,它的作用只有一個,就是在運行時通知虛擬機可以安全地在實現了此接口的類上使用clone方法。在java虛擬機中,只有實現了這個接口的類才可以被拷貝,否則在運行時會拋出CloneNotSupportedException異常。
- 重寫Object類中的clone方法。Java中,所有類的父類都是Object類,Object類中有一個clone方法,作用是返回對象的一個拷貝,但是其作用域protected類型的,一般的類無法調用,因此,Prototype類需要將clone方法的作用域修改為public類型。
三、實現
namespace DesignPatterns.Prototype {class Program{static void Main(string[] args){List<string> executors = new List<string>();executors.Add("張三");executors.Add("李四");Plan plan = new Plan();plan.SetName("重構前端登錄界面");plan.SetLevel(1);plan.SetStartdate(DateTime.Parse("2017-08-07"));plan.SetEnddate(DateTime.Parse("2017-08-09"));plan.SetExecutors(executors);Plan plan2 = plan.Clone();plan2.SetName("后端接口改造");plan2.SetLevel(2);plan2.SetStartdate(DateTime.Parse("2017-08-10"));plan2.SetEnddate(DateTime.Parse("2017-08-12"));Console.WriteLine("地址是否一樣?" + (plan == plan2));Console.WriteLine("plan.getName() == plan2.getName() " + (plan.GetName() == plan2.GetName()));Console.WriteLine("plan.getLevel() == plan2.getLevel() " + (plan.GetLevel() == plan2.GetLevel()));Console.WriteLine("plan.getStartdate() == plan2.getStartdate() " + (plan.GetStartdate() == plan2.GetStartdate()));Console.WriteLine("plan.getEnddate() == plan2.getEnddate() " + (plan.GetEnddate() == plan2.GetEnddate()));Console.WriteLine("plan.getExecutors() == plan2.getExecutors() " + (plan.GetExecutors() == plan2.GetExecutors()));Console.WriteLine("plan:" + plan.toString());Console.WriteLine("plan2:" + plan2.toString());//plan任務比較重,在給plan添加一個人executors.Add("王五");plan.SetExecutors(executors);Console.WriteLine();Console.WriteLine("地址是否一樣?" + (plan == plan2));Console.WriteLine("plan.getName() == plan2.getName() " + (plan.GetName() == plan2.GetName()));Console.WriteLine("plan.getLevel() == plan2.getLevel() " + (plan.GetLevel() == plan2.GetLevel()));Console.WriteLine("plan.getStartdate() == plan2.getStartdate() " + (plan.GetStartdate() == plan2.GetStartdate()));Console.WriteLine("plan.getEnddate() == plan2.getEnddate() " + (plan.GetEnddate() == plan2.GetEnddate()));Console.WriteLine("plan.getExecutors() == plan2.getExecutors() " + (plan.GetExecutors() == plan2.GetExecutors()));Console.WriteLine("plan:" + plan.toString());Console.WriteLine("plan2:" + plan2.toString());}}/*** 計劃* 【淺拷貝】*/public class Plan{//計劃名稱private string _name;//任務級別private int _level;//開始時間private DateTime _startdate;//截止時間private DateTime _enddate;//執行人員private List<string> _executors = new List<string>();public Plan Clone(){return this;}public string GetName(){return _name;}public void SetName(string name){this._name = name;}public DateTime GetStartdate(){return _startdate;}public void SetStartdate(DateTime startdate){this._startdate = startdate;}public DateTime GetEnddate(){return _enddate;}public void SetEnddate(DateTime enddate){this._enddate = enddate;}public List<string> GetExecutors(){return _executors;}public void SetExecutors(List<string> executors){this._executors = executors;}public int GetLevel(){return _level;}public void SetLevel(int level){this._level = level;}public string toString(){return "[name=" + _name + ", level=" + _level + ", startdate=" + _startdate + ", enddate=" + _enddate+ ", executors=" + _executors + "]";}} }?
四、適用場景
1、資源優化場景。
2、類初始化需要消化非常多的資源,這個資源包括數據、硬件資源等。
3、性能和安全要求的場景。
4、通過 new 產生一個對象需要非常繁瑣的數據準備或訪問權限,則可以使用原型模式。
5、一個對象多個修改者的場景。
6、一個對象需要提供給其他對象訪問,而且各個調用者可能都需要修改其值時,可以考慮使用原型模式拷貝多個對象供調用者使用。
7、在實際項目中,原型模式很少單獨出現,一般是和工廠方法模式一起出現,通過 clone 的方法創建一個對象,然后由工廠方法提供給調用者。
注意事項:與通過對一個類進行實例化來構造新對象不同的是,原型模式是通過拷貝一個現有對象生成新對象的。淺拷貝實現 Cloneable,重寫,深拷貝是通過實現 Serializable 讀取二進制流。
五、優缺點
優點:
1、對客戶端隱藏具體的實現類型:原型模式的客戶端,只知道原型接口的類型,并不知道具體的實現類型,從而減少了客戶端對這些具體實現類型的依賴。
2、在運行時動態改變具體的實現類型:原型模式可以在運行期間,由客戶來注冊符合原型接口的實現類型,也可以動態的改變具體的實現類型,看起來接口沒有任何變化,但其實運行的已經是另外一個類實例了。因為克隆一個原型就類似于實例化一個類。
缺點:
深度克隆方法實現會比較困難:原型模式最大的缺點就在于每個原型的子類都必須實現clone的操作,尤其在包含引用類型的對象時,clone方法會比較麻煩,必須要能夠遞歸的讓所有的相關對象都要正確的實現克隆。
?
參考:
http://www.cnblogs.com/JsonShare/p/7300124.html
http://www.runoob.com/design-pattern/prototype-pattern.html
?
?
歡迎閱讀本系列文章:Head First設計模式之目錄?
?
總結
以上是生活随笔為你收集整理的Head First设计模式之原型模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 装饰器前戏
- 下一篇: SQL基础(四):SQL命令