设计模式——原型模式
2015-08-16 21:24
253 查看
定义
用原型实例指定创建对象的种类,并且通过拷贝这些创建新的对象。
好处与使用场景
a.使用原型模式创建对象比直接new一个对象在性能上要好的多,因为Object类的clone方法是一个本地方法,它直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显。类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等
b.在性能和安全上,通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。
c.一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。
使用原型模式的一个好处是简化对象的创建,使得创建对象就像我们在编辑文档时的复制粘贴一样简单。
比如需要在一个循环体内创建对象,假如对象创建过程比较复杂或者循环次数很多的话,使用原型模式不但可以简化创建过程,而且可以使系统的整体性能提高很多。
原型模式结构图
例子:
.NET中在命名空间中提供了ICloneable接口,其中就是唯一的一个方法Clone(),只需要实现这个接口就可以完成原型模式。
原型类:简历
class Resume :ICloneable
{
private string name;
private string sex;
private string age;
private string timeArea;
private string company;
public Resume(string name)
{
this.name = name;
}
public void SetPersonalInfo(string sex, string age)
{
this.sex = sex;
this.age = age;
}
//工作经历
public void SetWorkExperience(string timeArea, string company)
{
this.timeArea = timeArea;
this.company = company;
}
//显示
public void Display()
{
Console.WriteLine("{0} {1} {2}", name, sex, age);
Console.WriteLine("工作经历:{0},{1}", timeArea, company);
}
//克隆方法
public Object Clone()
{
return (Object)this.MemberwiseClone();
}
}
客户端代码:
class Program
{
static void Main(string[] args)
{
//定义一个简历类(原型类)
Resume a = new Resume("大鸟");
a.SetPersonalInfo("男", "29");
a.SetWorkExperience("1998-2000", "XX公司");
Resume b = (Resume)a.Clone(); //克隆一个a对象
b.SetWorkExperience("1998-2006", "YY公司"); //重写b对象方法
Resume c = (Resume)a.Clone(); //再次克隆一个a对象
c.SetPersonalInfo("男", "24"); //重写c对象方法
//显示
a.Display();
b.Display();
c.Display();
Console.Read();
}
}
结果:
深复制与浅复制
上边举例就是浅复制,原型类中,如果包含一个对象,克隆原型类后得到的新类中也包含这个对象,而且和原型类中的包含的一个对象是一个对象,对谁修改都是修改的一个对象。
深复制就是通过一些方法把这个对象也克隆给新类中。
用原型实例指定创建对象的种类,并且通过拷贝这些创建新的对象。
好处与使用场景
a.使用原型模式创建对象比直接new一个对象在性能上要好的多,因为Object类的clone方法是一个本地方法,它直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显。类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等
b.在性能和安全上,通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。
c.一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。
使用原型模式的一个好处是简化对象的创建,使得创建对象就像我们在编辑文档时的复制粘贴一样简单。
比如需要在一个循环体内创建对象,假如对象创建过程比较复杂或者循环次数很多的话,使用原型模式不但可以简化创建过程,而且可以使系统的整体性能提高很多。
原型模式结构图
例子:
.NET中在命名空间中提供了ICloneable接口,其中就是唯一的一个方法Clone(),只需要实现这个接口就可以完成原型模式。
原型类:简历
class Resume :ICloneable
{
private string name;
private string sex;
private string age;
private string timeArea;
private string company;
public Resume(string name)
{
this.name = name;
}
public void SetPersonalInfo(string sex, string age)
{
this.sex = sex;
this.age = age;
}
//工作经历
public void SetWorkExperience(string timeArea, string company)
{
this.timeArea = timeArea;
this.company = company;
}
//显示
public void Display()
{
Console.WriteLine("{0} {1} {2}", name, sex, age);
Console.WriteLine("工作经历:{0},{1}", timeArea, company);
}
//克隆方法
public Object Clone()
{
return (Object)this.MemberwiseClone();
}
}
客户端代码:
class Program
{
static void Main(string[] args)
{
//定义一个简历类(原型类)
Resume a = new Resume("大鸟");
a.SetPersonalInfo("男", "29");
a.SetWorkExperience("1998-2000", "XX公司");
Resume b = (Resume)a.Clone(); //克隆一个a对象
b.SetWorkExperience("1998-2006", "YY公司"); //重写b对象方法
Resume c = (Resume)a.Clone(); //再次克隆一个a对象
c.SetPersonalInfo("男", "24"); //重写c对象方法
//显示
a.Display();
b.Display();
c.Display();
Console.Read();
}
}
结果:
深复制与浅复制
上边举例就是浅复制,原型类中,如果包含一个对象,克隆原型类后得到的新类中也包含这个对象,而且和原型类中的包含的一个对象是一个对象,对谁修改都是修改的一个对象。
深复制就是通过一些方法把这个对象也克隆给新类中。
相关文章推荐
- Android-网络提交数据get和post的两种方式
- seci-log 1.09 发布 日志分析增加了多个报表和功能点
- 常量指针与指针常量
- 实现多线程的两种方式
- gdb之初识
- 【C/C++学院】0828-数组与指针/内存分配/数据结构数组接口与封装
- CSS Alignment:元素对齐问题
- Android视图绘制流程完全解析,带你一步步深入了解View(二)
- MFC修改菜单
- 【JavaScript】AJax
- 102 Binary Tree Level Order Traversal
- POJ2007--Scrambled Polygon
- c++从零开始学起(关于迭代器的使用)
- hdu 4983 Goffi and GCD(欧拉函数)
- NOIP2010 引水入城
- 求最小的k个数
- 倒排索引
- 8.15总结
- Javascript 基础
- 使用Java快速实现进度条(转)