C# 设计模式一一原型模式

一、定义

原型模式,用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

二、结构图

原型模式其实就是从一个对象再创建另外一个可定制的对象,而且不需知道任何创建的细节。

三、实例

//工作经历类
class WorkExperience
{
	public string WorkDate
	{
		get;
		set;
	}

	public string Company
	{
		get;
		set;
	}
}
//简历类
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 );
	}

	/// <summary>
	/// 浅拷贝:针对引用类型只复制引用不复制引用对象,即原始对象和副本引用同一个对象
	/// </summary>
	/// <returns></returns>
	public Object Clone( )
	{
		return (Object)this.MemberwiseClone( );
	}
}
static void Main( string[ ] args )
{
	Resume a = new Resume( "andy" );
	a.SetPersonalInfo( "男", "18" );
	a.SetWorkExperience( "1992-2000", "XX公司" );

	Resume b = (Resume)a.Clone( );
	b.SetWorkExperience( "1992-2002", "XY公司" );

	Resume c = (Resume)a.Clone( );
	b.SetWorkExperience( "1992-2001", "YY公司" );

	a.Display( );
	b.Display( );
	c.Display( );
	Console.Read( );

}

运行结果:

      上述代码运行完成后,三次显示的结果都是最后一次设置的值。这是因为由于浅表复制,所以对于值类型,没什么问题,对引用类型,就只是复制了引用,对引用的对象还是指向了原来的对象,所以就会出现给a,b,c三个引用设置“工作经历”,却同时看到三个引用都是最后一次设置,因为三个引用都指向了同一个对象。

浅复制:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。

深复制:把引用对象的变量指向复制过来的新对象,而不是原有的被引用的对象。

简历的深复制实现:

//工作经历
class WorkExperience : ICloneable
{
	public string WorkDate
	{
		get;
		set;
	}

	public string Company
	{
		get;
		set;
	}

	//“工作经历”类实现克隆方法
	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 );
	}

	/// <summary>
	/// 深拷贝:把引用对象的变量指向复制过的新对象,而不是原有的被引用的对象。
	/// </summary>
	/// <returns></returns>
	public Object Clone( )
	{
		//调用私有构造方法,让“工作经历”克隆完成,此处克隆会调用私有构造函数中的(WorkExperience)work.Clone( )实现“工作经历”深拷贝
		Resume obj = new Resume( this.work );
		//给这个“简历”对象的相关字段赋值,最终返回一个深复制的简历对象
		obj.name = this.name;
		obj.sex = this.sex;
		obj.age = this.age;
		return obj;
	}
}
static void Main( string[ ] args )
{
	Resume a = new Resume( "andy" );
	a.SetPersonalInfo( "男", "18" );
	a.SetWorkExperience( "1992-2000", "XX公司" );

	Resume b = (Resume)a.Clone( );
	b.SetWorkExperience( "1992-2002", "YY公司" );

	Resume c = (Resume)a.Clone( );
	c.SetWorkExperience( "1992-2001", "ZZ公司" );

	a.Display( );
	b.Display( );
	c.Display( );
	Console.Read( );
}

运行结果:

       由于在一些特定场合,会经常涉及深复制或浅复制,比如说,数据集对象DataSet,它就有Clone()方法和Copy()方法。Clone()方法用来复制DataSet的结构,但不复制DataSet的数据,实现了原型模式的浅复制。Copy()方法不但复制结构,也复制数据,其实就是实现了原型模式的深复制。

四、原型模式的优缺点

原型模式的优点有:

  1. 原型模式向客户隐藏了创建新实例的复杂性
  2. 原型模式允许动态增加或较少产品类。
  3. 原型模式简化了实例的创建结构,工厂方法模式需要有一个与产品类等级结构相同的等级结构,而原型模式不需要这样。
  4. 产品类不需要事先确定产品的等级结构,因为原型模式适用于任何的等级结构

原型模式的缺点有:

  1. 每个类必须配备一个克隆方法
  2.  配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不一定很容易,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值