设计模式之原型模式(Prototype)
1、出现原因
在软件系统中,经常面临着“某些结构复杂的对象”的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是它们却拥有比较稳定一致的接口。
如何应对这种变化?如何向“客户程序(使用这些对象的程序)”隔离出“这些易变对象” ,从而使得“依赖这些易变对象的客户程序”不随着需求改变而改变?
2、意图:
使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建新的对象。(将相同的部分进行赋值拷贝,不同的部分需要客户端自己决定)
3、结构图
4、代码演示
举例:比如楼房的基本信息是相同的,但是他们的门牌号码是不同的,需要客户自己决定的。
//原型接口
public interface IBuildingPrototype
{
string BuildingName { set; get; }
string BuildingNo { set; get; }
IBuildingPrototype Clone();
}
//实现原型接口的类
public class Building : IBuildingPrototype
{
public string BuildingName
{
get;
set;
} public string BuildingNo
{
get;
set;
} public IBuildingPrototype Clone()
{
Building building = new Building();
building.BuildingName = this.BuildingName;
return building;
}
}
实现Prototype模式的代码
客户端调用代码:
Building b1 = new Building();
b1.BuildingName = "小别墅";
b1.BuildingNo = "B1203";
IBuildingPrototype b2 = b1.Clone();
b2.BuildingNo = "B1230";
Console.WriteLine(b2.BuildingName+":"+b2.BuildingNo);
使用.Net内部的原型模式的ICloneable接口实现版本
public class BuildingIclone : ICloneable
{
public string BuildingName { set; get; }
public string BildingNo { get; set; }
public object Clone()
{
BuildingIclone building = new BuildingIclone();
building.BuildingName = this.BuildingName;
return building;
}
}
5、深拷贝和浅拷贝
提到拷贝:就要想到深拷贝和浅拷贝,下面就来讲解他们之间的区别:
他们之间的区别是体现在他们之中的 引用类型的 属性的 拷贝方式,其他值类型和string类型的属性只是直接拷贝数值:
浅拷贝:只是拷贝 引用类型的引用指针,新拷贝出来的实例的此属性还是指向原来的实例的属性的“地址”。
深拷贝:是将引用类型的属性 从新在内存中 创建一份 然后赋值给新拷贝到实例对应的属性。
在.Net中实现浅拷贝的方式Object.MemberwiseClone();
实现深拷贝要自己写代码了,实现的方式有两种:1)将浅拷贝来的实例的引用类型的属性在从新赋值一个新的从内存中创建的实例。
2)使用序列化的方式实现深拷贝(将浅拷贝的实例进行序列化,然后再反序列化得到深拷贝的实例)
代码来演示:
//下面演示 :浅拷贝和深拷贝的区别
[Serializable]
public class WorkExperience : ICloneable
{
public string CompanyName { get; set; } public int Time { get; set; } public object Clone()
{
return this.MemberwiseClone();
} public override string ToString()
{
return string.Format("在{0}公司工作了{1}年",CompanyName,Time);
}
} [Serializable]
public class Worker : ICloneable
{
public string Name { get; set; } public int Age { get; set; } public WorkExperience WorkExprien { set; get; } //浅拷贝
public Worker QianClone()
{
return (Worker)this.MemberwiseClone();
} //深拷贝(将浅拷贝的实例的引用类型属性从新赋值的方式)
public object Clone()
{
Worker worker = (Worker)this.MemberwiseClone();
worker.WorkExprien = (WorkExperience)this.WorkExprien.Clone();
return worker;
} //深拷贝(序列化版本),要将要被序列化的类打上Serializable的特性
public Worker ShenClone()
{
Worker worker = (Worker) this.MemberwiseClone();
BinaryFormatter binary = new BinaryFormatter();
using (Stream stream = new MemoryStream())
{
binary.Serialize(stream, this);
stream.Position = ;//将当前流 重新定位,,否则会报错:“在分析完成之前就遇到流结尾。”
return (Worker) binary.Deserialize(stream);
}
} }
深拷贝和浅拷贝
测试代码:
Worker worker = new Worker()
{
Name = "小明",
Age = ,
WorkExprien = new WorkExperience() { CompanyName="百度",Time=}
}; Worker w1 = worker.QianClone();//浅拷贝
Worker w2 = (Worker)worker.Clone();//深拷贝
Worker w3 = worker.ShenClone();//序列化版本的深拷贝
Console.WriteLine(worker.WorkExprien.Equals(w1.WorkExprien));//True
Console.WriteLine(worker.WorkExprien.Equals(w2.WorkExprien));//False
Console.WriteLine(worker.WorkExprien.Equals(w3.WorkExprien));//False
测试代码
6、.Net中的原型模式
1》就是上面提到的ICloneable接口
2》DataSet
Clone()方法:浅拷贝:只复制表的结构,不复制表的数据
Copy()方法:深拷贝:既复制表的结构,又复制表的数据
7、实现要点
1、产品的创建和初始化在类的Clone方法中完成
2、浅复制与深复制的区别
3、需要深复制的场合需要开发人员根据需要实现(在重写的 Clone 里 将引用类型 成员进行复制)
4、有些情况下Clone功能不容易实现,特别是遇到对象的循环引用时(例如:A关联B,同时B也关联A:就是A中有B,同时B中也有A。这样就会造成,A中的Clone克隆的时候,要将 B进行克隆,同时在 B的Clone里面进行 克隆的时候A也就被同时复制了,所以会一直循环复制下去)
8、效果
在运行时增加或删除产品:只要通过客户原型实例即可将新产品类型增加到系统中,例如组态软件中工具箱中的每个工具可以对应一个注册的原型对象,可以通过增加原形对象扩展工具箱。
很容易地创建复杂的对象:在图形编辑和组态等软件中,经常需要创建复杂的图元。这些图元是由简单图元组成的,采用原型模式可以很容易地将复杂图元作为一般图元来使用,使软件的工具箱具有自扩展功能
9、适用性:
1、当一个系统应该独立于产品的创建、构成和表示时,可以使用原型模式。
2、在使用时,我们可以用一些原型对象来代替生成相应对象的工厂对象,并且可以使拷贝、粘贴等操作独立于需要复制的对象。
10、总结
1、Prototype模式同样用于隔离类对象的使用者和具体类型(易变类)之间的耦合关系(使用者不用关心,类内部的具体情况,直接复制就可以了),它同样要求这些“易变类”拥有“稳定的接口”。
2、Prototype模式对于“如何创建易变类的实体对象”采用“原型克隆”的方法来做,它使得我们可以非常灵活地动态创建“拥有某些稳定接口”的新对象——所需工作仅仅是注册一个新的对象(即原型)(只要已经创建一个就可以了),然后在任何需要的地方不断地Clone。
3、Prototype模式中的Clone方法可以利用.NET中的Object类的MemberwiseClone()方法(浅拷贝)或者序列化来实现深拷贝。
设计模式之原型模式(Prototype)的更多相关文章
- 乐在其中设计模式(C#) - 原型模式(Prototype Pattern)
原文:乐在其中设计模式(C#) - 原型模式(Prototype Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 原型模式(Prototype Pattern) 作者:weba ...
- 二十四种设计模式:原型模式(Prototype Pattern)
原型模式(Prototype Pattern) 介绍用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象.示例有一个Message实体类,现在要克隆它. MessageModel usin ...
- [设计模式] 4 原型模式 prototype
设计模式:可复用面向对象软件的基础>(DP)本文介绍原型模式和模板方法模式的实现.首先介绍原型模式,然后引出模板方法模式. DP书上的定义为:用原型实例指定创建对象的种类,并且通过拷贝这些原型创 ...
- 设计模式 笔记 原型模式 prototype
//---------------------------15/04/07---------------------------- //prototype 原型模式--对象创建型模式 /* 1:意图: ...
- python 设计模式之原型模式 Prototype Pattern
#引入 例子1: 孙悟空拔下一嘬猴毛,轻轻一吹就会变出好多的孙悟空来. 例子2:寄个快递下面是一个邮寄快递的场景:“给我寄个快递.”顾客说.“寄往什么地方?寄给……?”你问.“和上次差不多一样,只是邮 ...
- 【UE4 设计模式】原型模式 Prototype Pattern
概述 描述 使用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.如孙悟空猴毛分身.鸣人影之分身.剑光分化.无限剑制 原型模式是一种创建型设计模式,允许一个对象再创建另外一个可定制的对象, ...
- 【设计模式】—— 原型模式Prototype
前言:[模式总览]——————————by xingoo 模式意图 由于有些时候,需要在运行时指定对象时哪个类的实例,此时用工厂模式就有些力不从心了.通过原型模式就可以通过拷贝函数clone一个原有的 ...
- 创建型设计模式之原型模式(Prototype)
结构 意图 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 适用性 当要实例化的类是在运行时刻指定时,例如,通过动态装载:或者 为了避免创建一个与产品类层次平行的工厂类层次时:或 ...
- 设计模式五: 原型模式(Prototype)
简介 原型模式是属于创建型模式的一种,是通过拷贝原型对象来创建新的对象. 万能的Java超类Object提供了clone()方法来实现对象的拷贝. 可以在以下场景中使用原型模式: 构造函数创建对象成本 ...
- 设计模式之原型模式(prototype)
原理:拷贝自身对象实际上就是调用的拷贝构造函数,注意事项是这里的拷贝是深拷贝,即需要拷贝指针所指的内容 #include <stdio.h> #include <memory> ...
随机推荐
- jQuery无缝循环开源多元素动画轮播jquery.slides插件
详细内容请点击 初始化插件: 一款基于jQuery无缝轮播图插件,支持图内元素动画,可以自定义动画类型$(".slideInner").slide({slideContainer: ...
- 初见,Devexpress
[绥江一百]http://www.sj100.net 欢迎,进入绥江一百感谢点击[我的小网站,请大家多 ...
- fitsSystemWindow作用
fitsSystemWindows layout属性 英文文档注释为: Boolean internal attribute to adjust view layout based on system ...
- 我的博客模板(线框图wireframe)
不久前看到一篇介绍定制网页浏览的方法,当时就想着,我把我的博客页也修改下,在手机浏览的时候,也能漂亮的显示出来.以后写的文章的话,也可以分享的微信朋友圈里面和朋友分享. 具体步骤参考:http://w ...
- C#中调用API
介绍 API( Application Programming Interface ),我想大家不会陌生,它是我们Windows编程的常客,虽然基于.Net平台的C#有了强大的类库,但是,我们还是不能 ...
- VS2008简体中文正式版序列号
VS2008简体中文正式版序列号 1.Visual Studio 2008 Professional Edition:XMQ2Y-4T3V6-XJ48Y-D3K2V-6C4WT 2.Visual St ...
- Spring IoC容器的设计—3—次线
这里涉及的是主要接口关系,而具体的IoC容器都是在这个接口体系下实现的,比如DefaultListableBeanFactory,这个基本IoC容器的实现就是实现了ConfigurableBeanFa ...
- jquery.cookie.js 使用方法
Cookies 定义:让网站服务器把少量数据储存到客户端的硬盘或内存,从客户端的硬盘读取数据的一种技术: 下载与引入:jquery.cookie.js基于jquery:先引入jquery,再引入:jq ...
- setbuf
setbuf是linux中的C函数,主要用于打开和关闭缓冲机制. setbuf函数具有打开和关闭缓冲机制.为了带缓冲进行I/O,参数buf必须指向一个长度为BUFSIZ(定义在stdio.h头文件中) ...
- Mysql表基本操作
一. 创建表的方法 语法:create table 表名( 属性名数据类型完整约束条件, 属性名数据类型条完整约束件, ......... 属性名数据类型 ); (1)举例:1 create tabl ...