K書記錄-大話設計模式-原型模式

原型模式的淺複製與深複製

任務 : 寫多份履歷

UML :

1.建立履歷和內容

程式碼 :

public class Resume
    {
        private string name;
        private string sex;
        private string age;
        private string timeArea;
        private string company;
        public Resume(string name)
        {
            this.name = name;
        }
        public void SetPersonalInfo(string sex , string age)
        {
            this.sex = sex;
            this.age = age; 
        }
        public void SetWorkExperience(string timeArea, string company)
        {
            this.timeArea = timeArea;
            this.company = company;
        }
        public void Display()
        {
            Console.WriteLine($"name = {name} , sex = {sex} , age = {age}.");
            Console.WriteLine($"Work experience : {timeArea} , {company}");
        }
    }

說明 : 履歷上會寫到的一些基本訊息先定義好,名字、性別…等等

 

2.繼承ICloneable並實現Clone()方法

程式碼 :

 

public class Resume : ICloneable

.
.
.
    
public object Clone()
{
    return (object)this.MemberwiseClone();
}

說明 : 在Clone方法內複製一份自身別出來,該複製屬於淺複製

MSDN :

3.使用原型工廠

程式碼 :

        static void Main(string[] args)
        {
            Resume resumeA = new Resume("abc");
            resumeA.SetPersonalInfo("man", "32");
            resumeA.SetWorkExperience("1900-1999", "A Company");

            Resume resumeB = (Resume)resumeA.Clone();
            resumeB.SetWorkExperience("1900-2021", "A Company");

            Console.WriteLine("-----ResumeA-----");
            resumeA.Display();
            Console.WriteLine("-----ResumeB-----");
            resumeB.Display();
            Console.ReadLine();
        }

說明 :

a.建立resumeA並將履歷內容都設定好

b.resumeB淺複製resumeB的內容

c.resumeB有部分內容需要修改

d.寫出兩份履歷

 

小結 :

原型模式的使用時機是需要多次複製原內容時使用,複製後的資料都跟原資料一樣,減少了重複設定資料內容的動作,在此方案我名字打錯了,我只要將名字改掉後,之後複製的履歷都會依照修改後履歷的名字複製。

此範例為淺複製的範例,要是履歷的類別內還有其他類別的話則需要深複製,範例如下:

 

任務 : 深複製履歷

UML :

1.將原本在履歷類別的工作時間、公司名稱移到工作經驗類別內

程式碼 :

    public class WorkExperience :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 this.MemberwiseClone();
        }
    }

說明 :

淺複製無法將類別內的資料複製,只能依靠子類別內也執行Clone傳出該資料來達成子類別的複製。

 

2.修改履歷類別

程式碼 :

public 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();
        }

        public Resume(WorkExperience work)
        {
            this.work = (WorkExperience)work.Clone();
        }

        public void SetPersonalInfo(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($"{name},{sex},{age}");
            Console.WriteLine($"WorkExperience : {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;
        }
    }

說明 :

多了一個建構式傳入工作經驗,而履歷的回傳則是建立一個複製工作經驗的新履歷並填入原履歷內容才傳出,要是還有其他類別存在時該類別也需要寫Clone方法才能夠達成深複製。

 

新手上路,若有錯誤請不吝嗇指教,謝謝。