设计模式--原型模式
2015-08-16 22:02
447 查看
原型模式,网上定义:用原型指定创建对象的种类,并且通过拷贝这些原型创建新的对象。我的理解是,一次实例化,多次调用。
【什么时候用】
在我们代码编程过程中会涉及到很多代码重用部分,当我们需要重复创建相似的对象时就要考虑原型模式,它的好处在于我们创建对象的同时不需要考虑对象的细枝末节;而且在使用时只需要实例化一次,大大增加了系统的性能,换句话就是不用新初始化对象,动态获得对象运行时状态。
.net语言中在system命名空间中提供ICloneable接口,子类通过实现Clone()方法,就可以直接完成原型模式,该方法直接操作内存中二进制流,因此对性能的差别非常明显。
【如何使用】
在C#语言中,原型类Protype类只需要调用IConeable即可。子类通过实现父类的Clone方法即可。
【深复制与浅复制】
针对一个具体实现对象来说,上面的方法完全可以实现。但对象与对象之间往往存在引用关系,而MemberwiseClone()方法只能复制值类型的数据,比如string,int等,但字段是引用类型则不能复制引用该对象。
例如有这样一段代码:
<pre name="code" class="csharp">class student
{
<span> </span>private string name;
<span> </span>public string Name
<span> </span>{
<span> </span>get{return name;}
<span style="white-space:pre"> </span>set{name=value;}
<span> </span>}
<span> </span>private string id;
<span style="white-space:pre"> </span>public string ID
{
<span style="white-space:pre"> </span>get{return id; }
<span style="white-space:pre"> </span>set{id=value; }
<span style="white-space:pre"> </span>}
}
class School:IConeable
{
<span style="white-space:pre"> </span>private string grade;
<span style="white-space:pre"> </span>private string class;
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>private Student student;
<span style="white-space:pre"> </span>public School()
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>student=new Student(); //实例化学生对象
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>//设置年级
<span style="white-space:pre"> </span>private void SetGrade(string grade)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>this.grade=grade;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>//设置学生信息
<span style="white-space:pre"> </span>private void SetStudentInfo(string name,string id)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>this.name=name;
<span style="white-space:pre"> </span>this.id=id;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>//实现克隆方法
<span style="white-space:pre"> </span>public Object Clone()
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>return (Object) this.MemberwiseClone();
<span style="white-space:pre"> </span>}
}
//客户端
static void Main(String[] args)
{
<span style="white-space:pre"> </span>School school1=new School();
school.SetStudentInfo("张三","1");
<span style="white-space:pre"> </span>school.SetGrade("三年级");
School school2=school1.Clone()
school2.SetStudentInfo("李四","2");
school2.SetGrade("四年级");
}
运行结果保存为:
张三 1 三年级
张三 1 四年级
因为student对象不能被MemberWiseClone()方法复制,因此clone()方法只实现了年级的转换。
要想实现学生对象也可以被复制,则学生类也要继承ICloneable接口,实现clone()方法。
<pre name="code" class="csharp">class student
{
<span> </span>private string name;
<span> </span>public string Name
<span> </span>{
<span> </span>get{return name;}
<span> </span>set{name=value;}
<span> </span>}
<span> </span>private string id;
<span> </span>public string ID
{
<span> </span>get{return id; }
<span> </span>set{id=value; }
<span> </span>}
<pre name="code" class="csharp"><pre name="code" class="csharp"><span style="white-space:pre"> </span>public Object Clone()
<span> </span>{
<span> </span>return (Object) this.MemberwiseClone();
<span> </span>}
}
//学校对象的构造方法添加上student的clone()方法
<pre name="code" class="csharp"><pre name="code" class="csharp"><span style="white-space:pre"> </span>public School()
<span> </span>{
<span> </span>student=new Student(); //实例化学生对象
<span> </span>}
<pre name="code" class="csharp"><pre name="code" class="csharp"><span style="white-space:pre"> </span>public School(Student student)
<span> </span>{
<span> </span>this.student=(Student)student.Clone(); //实例化学生对象
<span> </span>}
//学校对象的clone()方法
public Object Clone()
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>School obj=new Schol(this.student);
<span style="white-space:pre"> </span>obj.grade=this.grade;
<span style="white-space:pre"> </span>obj.class=this.class;
<span style="white-space:pre"> </span>return obj;
<span style="white-space:pre"> </span>}
其实深复制远远不止应用于两个对象之间的调用,还可以应用于多级对象的调用关系。
【总结】
原型模式的设计大大增强了代码的重用性,提高了系统性能,同时深复制和浅复制的灵活运用让系统编写变得游刃有余。
【什么时候用】
在我们代码编程过程中会涉及到很多代码重用部分,当我们需要重复创建相似的对象时就要考虑原型模式,它的好处在于我们创建对象的同时不需要考虑对象的细枝末节;而且在使用时只需要实例化一次,大大增加了系统的性能,换句话就是不用新初始化对象,动态获得对象运行时状态。
.net语言中在system命名空间中提供ICloneable接口,子类通过实现Clone()方法,就可以直接完成原型模式,该方法直接操作内存中二进制流,因此对性能的差别非常明显。
【如何使用】
在C#语言中,原型类Protype类只需要调用IConeable即可。子类通过实现父类的Clone方法即可。
public Object Clone() { return (Object)this.MemberwiseClone();//object是所有子类的父类 }
【深复制与浅复制】
针对一个具体实现对象来说,上面的方法完全可以实现。但对象与对象之间往往存在引用关系,而MemberwiseClone()方法只能复制值类型的数据,比如string,int等,但字段是引用类型则不能复制引用该对象。
例如有这样一段代码:
<pre name="code" class="csharp">class student
{
<span> </span>private string name;
<span> </span>public string Name
<span> </span>{
<span> </span>get{return name;}
<span style="white-space:pre"> </span>set{name=value;}
<span> </span>}
<span> </span>private string id;
<span style="white-space:pre"> </span>public string ID
{
<span style="white-space:pre"> </span>get{return id; }
<span style="white-space:pre"> </span>set{id=value; }
<span style="white-space:pre"> </span>}
}
class School:IConeable
{
<span style="white-space:pre"> </span>private string grade;
<span style="white-space:pre"> </span>private string class;
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>private Student student;
<span style="white-space:pre"> </span>public School()
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>student=new Student(); //实例化学生对象
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>//设置年级
<span style="white-space:pre"> </span>private void SetGrade(string grade)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>this.grade=grade;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>//设置学生信息
<span style="white-space:pre"> </span>private void SetStudentInfo(string name,string id)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>this.name=name;
<span style="white-space:pre"> </span>this.id=id;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>//实现克隆方法
<span style="white-space:pre"> </span>public Object Clone()
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>return (Object) this.MemberwiseClone();
<span style="white-space:pre"> </span>}
}
//客户端
static void Main(String[] args)
{
<span style="white-space:pre"> </span>School school1=new School();
school.SetStudentInfo("张三","1");
<span style="white-space:pre"> </span>school.SetGrade("三年级");
School school2=school1.Clone()
school2.SetStudentInfo("李四","2");
school2.SetGrade("四年级");
}
运行结果保存为:
张三 1 三年级
张三 1 四年级
因为student对象不能被MemberWiseClone()方法复制,因此clone()方法只实现了年级的转换。
要想实现学生对象也可以被复制,则学生类也要继承ICloneable接口,实现clone()方法。
<pre name="code" class="csharp">class student
{
<span> </span>private string name;
<span> </span>public string Name
<span> </span>{
<span> </span>get{return name;}
<span> </span>set{name=value;}
<span> </span>}
<span> </span>private string id;
<span> </span>public string ID
{
<span> </span>get{return id; }
<span> </span>set{id=value; }
<span> </span>}
<pre name="code" class="csharp"><pre name="code" class="csharp"><span style="white-space:pre"> </span>public Object Clone()
<span> </span>{
<span> </span>return (Object) this.MemberwiseClone();
<span> </span>}
}
//学校对象的构造方法添加上student的clone()方法
<pre name="code" class="csharp"><pre name="code" class="csharp"><span style="white-space:pre"> </span>public School()
<span> </span>{
<span> </span>student=new Student(); //实例化学生对象
<span> </span>}
<pre name="code" class="csharp"><pre name="code" class="csharp"><span style="white-space:pre"> </span>public School(Student student)
<span> </span>{
<span> </span>this.student=(Student)student.Clone(); //实例化学生对象
<span> </span>}
//学校对象的clone()方法
public Object Clone()
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>School obj=new Schol(this.student);
<span style="white-space:pre"> </span>obj.grade=this.grade;
<span style="white-space:pre"> </span>obj.class=this.class;
<span style="white-space:pre"> </span>return obj;
<span style="white-space:pre"> </span>}
其实深复制远远不止应用于两个对象之间的调用,还可以应用于多级对象的调用关系。
【总结】
原型模式的设计大大增强了代码的重用性,提高了系统性能,同时深复制和浅复制的灵活运用让系统编写变得游刃有余。
相关文章推荐
- PropertyChangeListener简单理解
- 什么是设计模式
- 设计模式之创建型模式 - 特别的变量问题
- 七、设计模式——装饰模式
- 设计模式总结
- 设计模式之创建型模式
- 浅谈设计模式的学习
- PHP设计模式之装饰者模式代码实例
- php设计模式之单例模式实例分析
- 介绍php设计模式中的工厂模式
- PHP设计模式之适配器模式代码实例
- 浅谈c#设计模式之单一原则
- C#设计模式之观察者模式实例讲解
- C#设计模式之单例模式实例讲解
- 深入理解JavaScript系列(28):设计模式之工厂模式详解
- 面向对象设计模式的核心法则
- JavaScript设计模式之单件模式介绍
- 深入理解JavaScript系列(25):设计模式之单例模式详解
- JavaScript设计模式之外观模式实例
- 常见的PHP五种设计模式小结