设计模式--原型模式
原型模式,网上定义:用原型指定创建对象的种类。而且通过拷贝这些原型创建新的对象。我的理解是,一次实例化。多次调用。
【什么时候用】
在我们代码编程过程中会涉及到非常多代码重用部分,当我们须要反复创建相似的对象时就要考虑原型模式,它的优点在于我们创建对象的同一时候不须要考虑对象的细枝末节。并且在使用时仅仅须要实例化一次,大大添加了系统的性能,换句话就是不用新初始化对象,动态获得对象执行时状态。
.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>} } //client 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>}
事实上深复制远远不止应用于两个对象之间的调用,还能够应用于多级对象的调用关系。
【总结】
原型模式的设计大大增强了代码的重用性。提高了系统性能,同一时候深复制和浅复制的灵活运用让系统编写变得游刃有余。