原型模式定義:
用原型實體指定創建物件的種類,并且通過拷貝這些原型創建新的物件,
原型模式其實就是從一個物件再創建另外一個可定制的物件,而且不需要知道任何創建的細節,

//原型類
abstract class Prototype
{
private string id;
public Prototype(string id)
{
this.id = id;
}
public string Id
{
get { return id; }
}
//抽象類關鍵方法
public abstract Prototype Clone();
}
//具體原型類
class ConcretePrototypel:Prototype
{
public ConcretePrototypel(string id):base(id)
{
}
public override Prototype Clone()
{
//方法重寫
return (Prototype)this.MemberwiseClone();
}
}
可以看到在具體類中我們實作了原型類中的克隆方法,其實在.net中克隆很常用就不必用原型類就可以直接實作克隆(剛剛知道),直接在命名空間中提供ICloneable介面就可以實作克隆了,
static void Main(string[] args)
{
ConcretePrototypel p1 = new ConcretePrototypel("I");
ConcretePrototypel c1 = (ConcretePrototypel)p1.Clone();
Console.WriteLine("Cloned:{0}", c1.Id);
Console.Read();
}
下面這個是通過用了克隆介面的原型模式代碼,以復制作業簡歷為背景故事
//簡歷類
class Resume:ICloneable
{
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("{0} {1} {2}", name, sex, age);
Console.WriteLine("作業經歷:{0} {1}", timeArea, company);
}
public Object Clone()
{
return (Object)this.MemberwiseClone();
}
}
//客戶端
static void Main(string[] args)
{
Resume a = new Resume("大鳥");
a.SetPersonalInfo("男", "29");
a.SetWorkExperience("1998-2000", "xx公司");
//呼叫Clone方法就可以實作新簡歷的生成,并且可以再修改新簡歷的細節
Resume b = (Resume)a.Clone();
b.SetWorkExperience("1998-2006", "YY公司");
Resume c = (Resume)a.Clone();
c.SetPersonalInfo("男", "24");
a.Display();
b.Display();
c.Display();
Console.Read();
}
這個原型模式的克隆還出現了兩種不同的情況,分別是淺復制和深復制,
淺復制
如果復制的欄位是 值型別的,則對該欄位執行逐位復制,如果欄位是參考型別的,則復制參考但不復制參考的物件,(復制參考:復制的參考地址,并沒有實際復制它的物件,所以后出現復制了多個參考型別的欄位并且修改后出現結果為最后修改的值)
被復制物件的所用變數都含有與原來的物件相同的值,而所有的對其他物件的參考仍然都指向原來的物件,
//作業經歷類
class WorkExperience
{
private string workDate;
public string WorkDate
{
get { return workDate; }
set { workDate = value; }
}
private string company;
public string Company
{
get { return company; }
set { company = value; }
}
}
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 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("{0} {1} {2}", name, sex, age);
Console.WriteLine("作業經歷:{0} {1}", work.WorkDate, work.Company);
}
public Object Clone()
{
return (Object)this.MemberwiseClone();
}
}


深復制
把參考物件的變數指向復制過的新物件,而不是原有的被參考的物件,

//作業經歷類
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 (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();
}
//提供Clone方法呼叫的私有建構式,以便于克隆作業經歷的資料
private 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("{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;
}
}

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/262125.html
標籤:其他
