using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace 原型模式
{
/*
* 原型模式意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
* 原型模式实现要点:1、使用原型管理器,体现在一个系统中原型数目不固定时,可以动态的创建和销毁
* 2、实现克隆操作,在.NET中可以使用Object类的MemberwiseClone()方法来实现对象的浅表拷贝或通过序列化的方式来实现深拷贝。
* 3、Prototype模式同样用于隔离类对象的使用者和具体类型(易变类)之间的耦合关系,它同样要求这些“易变类”拥有稳定的接口。
*
* 原型模式优点:1、Prototype模式运行动态增加或减少产品类。由于创建产品实力的方法是产品类内部具有的,因此新增产品对整个结构没有影响。
* 2、原型模式提供了另外的创建结构,工厂方法模式常常需要有一个与产品类等级接口相同的等级结构,而原型模式就不需要这样。
* 3、Portotype模式具有给一个应用软件动态加载新功能的能力。由于Prototype的独立性较高,可以很容易动态加载新功能而不影响老系统
* 4、产品类不需要非得有任何事先确定的等级结构, 因为Prototype模式适用于任何的等级结构
* 5、减少了子类构造,Prototype模式是克隆一个原型而不是请求工厂方法创建一个,所以它不需要一个与具体产品类平行的Creater类层次。
*
* 原型模式缺点:1、每一个类必须配备一个克隆方法。而且这个克隆方法需要对类的功能进行通盘考虑,这对全新的类来说不是很难,但对已有的类进行改造时,不一定是件容易的事
*
* 原型模式使用场景:1、当一个系统应该独立于它的产品创建,构成和表示时。
* 2、当要实例化的类是在运行时刻指定时,如动态加载。
* 3、为了避免创建一个与产品类层次平行的工厂类层次时
* 4、当一个类的实例只能有几个不同状态中的一种时,建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便些。
* 5、当类的初始化需要消耗非常多的资源,但系统却需要不少这些类的对象时
* 6、当通过new产生一个对岸需要非常繁琐的数据准备或访问权限,则可以使用原型模式
*
* 原型模式使用效果:1、减少客户隐藏具体的产品类,因此减少了客户知道的名字的数目。
* 2、原型模式运行客户只通过注册原型实例就可以将一个具体产品并入到系统中,客户可以在运行时刻简历和删除原型。
* 3、减少了子类的构造,因为原型模式是克隆一个原型而不是请求工厂方法创建一个,所以它不需要一个与具体产品类平行的Creator类层次
* 4、由于原型模式是在内存二进制流的拷贝,要比直接new一个对象性能好很多,同时也避免了构造函数的约束。
* 特别是要找一个循环体内产生大量的对象时,原型模式可以更好地体现其优点。
*/
/// <summary>
/// 需要克隆的原型类
/// </summary>
public abstract class Protype
{
/// <summary>
/// 需克隆的字段
/// </summary>
private string _id;
public Protype(string id)
{
this._id = id;
}
public string Id
{
get { return _id; }
set { _id = value; }
}
/// <summary>
/// 定义其需要克隆的的抽象方法
/// </summary>
/// <returns></returns>
public abstract Protype Clone();
}
/// <summary>
/// 具体的原型扩展类1(可以添加新的方法)
/// </summary>
public class ConcreteProtype1 : Protype
{
/// <summary>
/// 继承父类需要克隆的属性或字段
/// </summary>
/// <param name="id"></param>
public ConcreteProtype1(string id)
: base(id)
{
}
/// <summary>
/// 实现父类的克隆方法
/// </summary>
/// <returns></returns>
public override Protype Clone()
{
//使用.net平台的浅复制方法g
return (Protype)this.MemberwiseClone();
}
}
/// <summary>
/// 具体的原型扩展类2
/// </summary>
public class ConcreteProtype2 : Protype
{
public ConcreteProtype2(string id)
: base(id)
{
}
public override Protype Clone()
{
return (Protype)this.MemberwiseClone();
}
}
/// <summary>
/// 客户调用,不过一般使用可以通过增加原型管理器的方法,方便管理
/// </summary>
public class AppClient
{
public static void Main(string[] args)
{
//创建原型1
ConcreteProtype1 p1 = new ConcreteProtype1("原型一ID");
//使用原型克隆的方式创建新的对象
ConcreteProtype1 c1 = (ConcreteProtype1)p1.Clone();
Console.WriteLine("Cloned: {0}", c1.Id);
ConcreteProtype2 p2 = new ConcreteProtype2("原型二ID");
ConcreteProtype2 c2 = (ConcreteProtype2)p2.Clone();
Console.WriteLine("Cloned: {0}", c2.Id);
}
}
}