原型模式 - OK

  原型模式(Prototype),用原型實例指定建立對象的種類,而且經過拷貝這些原型建立新的對象。javascript

  簡單說來原型模式就是從一個對象再建立另一個可定製的對象,並且不需知道任何建立的細節。html

  原型模式UML圖:java

    

  原型模式的基本代碼結構:git

複製代碼
namespace ConsoleApplication1
{
    abstract class Prototype
    {
        private string id;

        public Prototype(string id)
        {
            this.id = id;
        }

        public string Id
        {
            get { return id; }
        }

        public abstract Prototype Clone();  //抽象類的關鍵就是要有這樣一個克隆方法
    }

    //具體原型類
    class ConcretePrototype1 : Prototype 
    {
        public ConcretePrototype1(string id): base(id)
        { 
            
        }

        public override Prototype Clone()
        {
            return (Prototype)this.MemberwiseClone();   //建立當前對象的淺表副本。方法是建立一個新對象,而後將當前對象的非靜態字段複製到該新對象。
                                                        //若是字段是值類型,則對該字段執行逐位複製,若是字段是引用類型,則複製引用但不復制引用的對象
                                                        //所以,原始對象及其副本引用贊成對象
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            ConcretePrototype1 p1 = new ConcretePrototype1("I");
            ConcretePrototype1 c1 = (ConcretePrototype1)p1.Clone();     //原型模式建立對象
            Console.WriteLine("Cloned:{0}",c1.Id);  //輸出 Cloned:I

            Console.ReadKey();
        }
    }  
}
複製代碼

  原型模式的做用:咱們知道每new一次對象,都須要執行一次構造函數,若是構造函數的執行時間很長,那麼屢次的執行初始化操做就比較低效。一半在初始化的信息不發生變化的狀況下,克隆是最好的辦法,這既隱藏了對象建立的細節,又能對性能是大大的提升。不用從新初始化對象,而是動態地得到對象運行時的狀態。設計模式

  在使用原型模式中,有必要注意淺複製與深複製的概念。ide

  對於上面的原型結構示例代碼:咱們知道若是字段是值類型的,則對該字段執行逐位複製,若是字段是引用類型的,則複製引用但不復制引用的對象;所以,原始對象及其副本引用贊成對象。函數

  淺複製:被複制對象的全部變量都含有與原來對象相同的值,而全部的對其餘對象的引用都仍然指向原來的對象。也就是說,淺複製複製出來的對象,若是裏面含有引用類型的數據,則淺複製複製出來的對象與原對象是同一個,由於僅複製引用地址嘛。post

  深複製:當執行復制時,被複制的對象含有引用類型對象的變量時,引用類型的變量對象也從新複製一份,即複製出來的引用對象與原類中的對象不是指向同一個地址。性能

  所以,在使用原型模式時必需要分析好,是該淺複製仍是深複製。學習

  回到《大話設計模式中的示例》 簡歷的原型實現:

複製代碼
namespace ConsoleApplication1
{
    class WorkExperience : ICloneable   //主要,要讓工做經歷實現ICloneable
    {
        private string workDate;
        public string WorkDate
        {
            get { return workDate; }
            set { workDate = value; }
        }

        private string company;
        public string Company
        {
            get { return company; }
            set { company = value; }
        }

        public Object Clone()
        {
            return (Object)this.MemberwiseClone();
        }
    }
    
    //簡歷類
    class Resume : ICloneable
    {
        private string name;
        private string sex;
        private string age;
        private WorkExperience work;

        public Resume(string Name)
        {
            this.name = Name;
            work = new WorkExperience();
        }

        private Resume(WorkExperience Work)
        {
            this.work = (WorkExperience)Work.Clone();   //注意深複製必需要添加此段代碼,提供Clone方法調用的私有構造函數以便剋制工做經歷
        }

        //設置我的信息
        public void SetPersonnalInfo(string Sex, string Age)
        {
            this.sex = Sex;
            this.age = Age;
        }

        //設置工做經歷
        public void SetWorkExperience(string workDate, string company)
        {
            work.WorkDate = workDate;
            work.Company = company;
        }

        //顯示
        public void Display()
        {
            Console.WriteLine("{0} {1} {2}",name,sex,age);
            Console.WriteLine("工做經歷:{0} {1}", work.WorkDate, work.Company);
        }

        public Object Clone()
        {
            Resume obj = new Resume(this.work);
            obj.name = this.name;
            obj.sex = this.sex;
            obj.age = this.age;
            return obj;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Resume a = new Resume("大鳥");
            a.SetPersonnalInfo("","29");
            a.SetWorkExperience("1998-2000","微軟");

            Resume b = (Resume)a.Clone();
            b.SetWorkExperience("2000-2004","google");

            Resume c = (Resume)a.Clone();
            c.SetPersonnalInfo("","24");
            c.SetWorkExperience("1998-2004","蘋果");

            a.Display();
            b.Display();
            c.Display();

            Console.ReadKey();
        }
    }  
}
複製代碼

  

 
 
分類: 設計模式
 
0
0
 
(請您對文章作出評價)
 
« 上一篇: 工廠方法模式 - OK
» 下一篇: 模板方法模式- 設計模式學習
相關文章
相關標籤/搜索