【大話設計模式】—— 原型模式

ZeroWM發表於2014-06-14

一、概念

  為了提高效率,我們經常會採用複製的方式,這樣不用一點一點的從頭開始進行(初始化新物件),直接利用結果就好(動態的獲得物件執行時的狀態)。

  前幾天我做演講的ppt,就有偷懶之嫌~ 把大家的優秀部落格,截圖然後copy到ppt當中,這樣免去了重新構思這一環節,高質量(大家的功勞 O(∩_∩)O~),高效率。

  設計模式中也不乏類似功能的模式。原型模式便是其中之一。

  原型模式(Prototype):用原型例項指定建立物件的種類,並且通過拷貝這些原型建立新的物件。不需要知道任何建立的細節。


二、UML圖

客戶(Client)物件:使用原型物件的客戶程式

抽象原型(Prototype)物件:宣告瞭克隆自身,且具體原型物件必須實現的介面(如果是深複製,必須有實現clone的規定)。

具體型別(ConcretePrototype)物件:從抽象原型派生而來,是客戶程式使用的物件,即被複制的物件。此角色需要實現抽象原型角色所要求的介面,實現一個克隆自身的操作。


三、例項解析

  學習了設計模式之後,小M終於有了一份工作(滿18了,木有非法使用童工。。)。為了獲得更多推銷自己的機會,她設計了一張自己的名片,包含的資訊有:姓名 性別 年齡 電話。但是一張名片送人之後,就再也沒有了,所以她通過原型模式又給自己copy了幾張。


   //客戶端程式碼
    class Program
    {
        static void Main(string[] args)
        {
            ConcreteBussinessCard bc = new ConcreteBussinessCard("小M");
            bc.SetPersonalInfo("女","18","12345678901");

            //克隆類ConcreteBussinessCard的物件bc就能得到新的例項bc1
            ConcreteBussinessCard bc1 = (ConcreteBussinessCard)bc.Clone();
            bc1.SetPersonalInfo("女", "18", "12345678901");

            bc.Display();
            bc1.Display();

            Console.Read();
          
           
        }
    }

    //抽象名片類
    abstract class BussinessCard
    {
        //定義名片包含資訊:姓名,性別,年齡,電話號碼為私有變數
        private string name;      
        private string sex;
        private string age;  
        private string phoneNumber; 


        //建構函式
        public BussinessCard(string name)
        {
            this.name = name;           
        }

        //設定個人資訊
        public void SetPersonalInfo(string sex, string age,string phoneNumber)
        {
            this.sex = sex;
            this.age = age;
            this.phoneNumber = phoneNumber;
        }

        //顯示
        public void Display()
        {
            Console.WriteLine("姓名:{0}  性別:{1}  年齡:{2}",name ,sex ,age );
            Console.WriteLine(" 電話:{0}",phoneNumber );

        }

        //關鍵是這裡有一個Clone方法
        public abstract BussinessCard Clone();
        
    }



    //具體名片類
    class ConcreteBussinessCard : BussinessCard
    {
        public ConcreteBussinessCard(string name)
            : base(name)
        { }


        public override BussinessCard Clone()
        {
            return (BussinessCard)this.MemberwiseClone();//建立當前的淺表副本。
        }
    }

}


執行結果:



四、深複製和淺複製

  背景:MemberwiseClone()方法是這樣,如果欄位是值型別的,則對該欄位執行逐位複製,如果欄位是引用型別,則複製引用但不復制引用的物件;因此,原始物件及其複本引用同一物件。



淺複製:被複制物件的所有變數都含有與原來的物件相同的值,而所有的對其他物件的引用都仍然指向原來的物件。

深複製:把引用物件的變數指向複製過的新物件,而不是原有的被引用的物件。


五、總結

  原型模式能夠簡化程式碼,優化設計,讓我們擺脫了手工抄寫的時代。程式碼同樣可以推動社會進步!


Ps:對深複製和淺複製的理解還很淺,看了一些大牛的部落格,也不是很明白,期待大家的點撥!

相關文章