原型模式(Prototype)
模式定义
原型模式是一种创建型设计模式,Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建。
UML类图

- 抽象原型 定义复制方法clone()方法
 - 具体原型  实现抽象原型中的复制方法 
this.MemberwiseClone() - 客户端调用
 
代码结构
MemberwiseClone()方法是Object对象的浅复制的方法。
	public static class Client
	{
		public static void Run()
		{
			ConcretePrototype p = new ConcretePrototype("I");
			ConcretePrototype c = (ConcretePrototype)p.Clone();
			if(p != c)
			{
				Console.WriteLine("The Copy Object is not same.");
			}
			Console.WriteLine(c.Id);
		}
	}
 
	public abstract class Prototype
	{
		private string _id;
		public Prototype(string id)
		{
			this._id = id;
		}
		public string Id
		{
			get { return _id; }
		}
		public abstract Prototype Clone();
	}
	public class ConcretePrototype : Prototype
	{
		public ConcretePrototype(string id) : base(id)
		{
		}
		public override Prototype Clone()
		{
			return (Prototype)this.MemberwiseClone();
		}
	}
C#代码优化
其实没必要定义抽象原型对象,如那个类需要具有复制的功能,直接继承ICloneable接口就可以了
	public class ConcretePrototype : ICloneable
	{
		private string _id;
		public string Id
		{
			get { return _id; }
		}
		public ConcretePrototype(string id) 
		{
			this._id = id;
		}
		public object Clone()
		{
			return this.MemberwiseClone();
		}
	}
深度复制
以上谈论的类中不包含引用类型成员(string类型除外,因每次操作其实新建一个对象,可当作值类型处理)。如果包含引用成员,以上为浅复制(即引用成员被对象和复制对象公用)。这是有两种解决办法:
- 通过递归对象内引用成员(
string除外)执行clone()(实现复杂) - 通过序列化与反序列化(实现简单)
通过序列化深度复制对象,假设一Person类对象有一Address类型属性,Address为引用类型。 
public static class PrototypeClient
	{
		public static void Run()
		{
			Person p1 = new Person() { Name = "LoveTomato", Address = new Address("China", "BeiJing", "Haidian") };
			Person p2 = p1.Clone() as Person;
			p2.Address.Area = "Chaoyang";
			Console.Write("\nName:{0},Address{1}", p1.Name, p1.Address.ToString());
			Console.Write("\nName:{0},Address{1}", p2.Name, p2.Address.ToString());
		}
	}
	[Serializable]
	public class Person : ICloneable
	{
		public string Name { get; set; }
		public Address Address { get; set; }
		public object Clone()
		{
			BinaryFormatter bf = new BinaryFormatter();
			MemoryStream ms = new MemoryStream();
			bf.Serialize(ms, this);
			ms.Position = 0;
			return (bf.Deserialize(ms));
		}
	}
	[Serializable]
	public class Address
	{
		public string Country { get; set; }
		public string City { get; set; }
		public string Area { get; set; }
		public Address(string country, string city, string area)
		{
			this.Country = country;
			this.City = city;
			this.Area = area;
		}
		public override string ToString()
		{
			return string.Format("Country:{0},City:{1},Area:{2}", this.Country, this.City, this.Area);
		}
	}
情景模式
在新建一个对象花费代价比较大时(需要从数据库或远程获取数据等),可以使用原型法创建对象。
在对数据库中数据修改做日志时,要求记录修改前值与修改后值。因为项目通过ORM操作数据库,则可先根据原型创建一对象作为修改前值(如果从数据库中查找两次比较耗时)。

                
            
        
浙公网安备 33010602011771号