《07 C#设计模式-原型模式.ppt》由会员分享,可在线阅读,更多相关《07 C#设计模式-原型模式.ppt(26页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、www.ChinaSA.infoDDesign esign P Patternsatterns原型模式原型模式原型模式原型模式刘刘 伟伟(Sunny)weiliu_www.ChinaSA.info大纲w原型模式概述w原型模式的结构与实现w原型模式的应用实例w原型管理器w原型模式的优缺点与适用环境www.ChinaSA.info原型模式概述w孙悟空“拔毛变小猴”www.ChinaSA.info原型模式概述w分析孙悟空:根据自己的形状孙悟空:根据自己的形状复制(克隆)复制(克隆)出多个身外身出多个身外身软件开发:通过复制一个软件开发:通过复制一个原型对象原型对象得到多个与原型对得到多个与原型对象一
2、模一样的新对象象一模一样的新对象原型模式原型模式www.ChinaSA.info原型模式概述w原型模式的定义对象创建型对象创建型模式模式原原型型模模式式:使用原型实例指定待创建对象的类型,并且通通过过复制复制这这个原型来个原型来创创建新的建新的对对象象。Prototype Pattern:Specify the kinds of objects to create using a prototypical instance,and create new objects by copying this prototype.www.ChinaSA.info原型模式概述w原型模式的定义工作原理:工作
3、原理:将一个原型对象传给要发动创建的对象(即客户将一个原型对象传给要发动创建的对象(即客户端对象),这个要发动创建的对象端对象),这个要发动创建的对象通过请求原型对象复制自通过请求原型对象复制自己来实现创建过程己来实现创建过程创建新对象(也称为克隆对象)的创建新对象(也称为克隆对象)的工厂工厂就是就是原型类原型类自身,自身,工工厂方法厂方法由负责复制原型对象的由负责复制原型对象的克隆方法克隆方法来实现来实现通过克隆方法所创建的对象是通过克隆方法所创建的对象是全新的对象全新的对象,它们在内存中拥,它们在内存中拥有新的地址,每一个克隆对象都是有新的地址,每一个克隆对象都是独立独立的的通过不同的方式
4、对克隆对象进行修改以后,通过不同的方式对克隆对象进行修改以后,可以得到一系列可以得到一系列相似但不完全相同的对象相似但不完全相同的对象www.ChinaSA.info原型模式的结构与实现w原型模式的结构www.ChinaSA.info原型模式的结构与实现w原型模式的结构原型模式包含以下原型模式包含以下3个角色:个角色:Prototype(抽象原型类)ConcretePrototype(具体原型类)Client(客户类)www.ChinaSA.info原型模式的结构与实现w浅克隆与深克隆浅克隆浅克隆(Shallow Clone):当原型对象被复制时,当原型对象被复制时,只只复制它本身和其中包含的
5、值类型的成员变量,而引用复制它本身和其中包含的值类型的成员变量,而引用类型的成员变量并没有复制类型的成员变量并没有复制www.ChinaSA.info原型模式的结构与实现w浅克隆与深克隆深克隆深克隆(Deep Clone):除了对象本身被复制外,除了对象本身被复制外,对象对象所包含的所有成员变量也将被复制所包含的所有成员变量也将被复制www.ChinaSA.info原型模式的结构与实现w原型模式的实现通用的克隆实现方法通用的克隆实现方法abstract class Prototype public abstract Prototype Clone();class ConcretePrototy
6、pe:Prototype private string attr;/成员变量 public string Attr get return attr;set attr=value;/克隆方法克隆方法 public override Prototype Clone()ConcretePrototype prototype=new ConcretePrototype();prototype.Attr=attr;return prototype;ConcretePrototype prototype=new ConcretePrototype();ConcretePrototype copy=(Con
7、cretePrototype)prototype.Clone();www.ChinaSA.info原型模式的结构与实现w原型模式的实现C#中的中的MemberwiseClone()方法和方法和ICloneable接接口口在C#语言中,提供了一个MemberwiseClone()方法用于实现浅克隆,该方法使用起来很方便,直接调用一个已有对象的MemberwiseClone()方法即可实现克隆/成员类class Memberclass ConcretePrototypeAprivate Member member;/成员对象public Member Memberget return member
8、;set member=value;/克隆方法克隆方法public ConcretePrototypeA Clone()return(ConcretePrototypeA)this.MemberwiseClone();/浅克隆浅克隆ConcretePrototypeA prototype,copy;prototype=new ConcretePrototypeA();copy=prototype.Clone();Console.WriteLine(prototype=copy);Console.WriteLine(prototype.Member=copy.Member);FalseTruew
9、ww.ChinaSA.info原型模式的结构与实现w原型模式的实现C#中的中的MemberwiseClone()方法和方法和ICloneable接接口口在C#语言中还提供了一个ICloneable接口,它也可以用来创建当前对象的副本ICloneable接口充当了抽象原型类的角色,具体原型类通常作为实现该接口的子类public interface ICloneable object Clone();class ConcretePrototypeB:ICloneable/实现实现ICloneable接口接口private Member member;public Member Memberget
10、return member;set member=value;/实现实现深克隆深克隆 public object Clone()ConcretePrototypeB copy=(ConcretePrototypeB)this.MemberwiseClone();Member newMember=new Member();copy.Member=newMember;return copy;ConcretePrototypeB prototype,copy;prototype=new ConcretePrototypeB();copy=(ConcretePrototypeB)prototype.C
11、lone();Console.WriteLine(prototype=copy);Console.WriteLine(prototype.Member=copy.Member);FalseFalsewww.ChinaSA.info原型模式的应用实例w实例说明在使用某OA系统时,有些岗位的员工发现他们每周的工作都大同小异,因此在填写工作周报时很多内容都是重复的,为了提高工作周报的创建效率,大家迫切地希望有一种机制能够快速创建相同或者相似的周报,包括创建周报的附件。试使用原型模式对该OA系统中的工作周报创建模块进行改进。www.ChinaSA.info原型模式的应用实例w实例类图工作周报创建模块结
12、构图工作周报创建模块结构图www.ChinaSA.info原型模式的应用实例w实例代码(1)WeeklyLog:周报类,充当原型角色:周报类,充当原型角色(2)Attachment:附件类:附件类(3)Program:客户端测试类:客户端测试类演示演示演示演示参考代码参考代码(DesignPatternPrototypeSample)www.ChinaSA.info原型模式的应用实例w结果及分析周报对象被成功复制,但是附件对象并没有复制,实周报对象被成功复制,但是附件对象并没有复制,实现了现了浅克隆浅克隆周报是否相同?否附件是否相同?是www.ChinaSA.info原型模式的应用实例w深克隆
13、解决方案将周报类将周报类WeeklyLog和附件类和附件类Attachment标记为标记为可可序列化序列化(Serializable)Serializableclass WeeklyLog private Attachment attachment;Serializableclass Attachmentwww.ChinaSA.info原型模式的应用实例w深克隆解决方案修改周报类修改周报类WeeklyLog的的Clone()方法方法/使用序列化方式实现深克隆public WeeklyLog Clone()WeeklyLog clone=null;FileStream fs=new FileSt
14、ream(Temp.dat,FileMode.Create);BinaryFormatter formatter=new BinaryFormatter();try formatter.Serialize(fs,this);/序列化序列化 catch(SerializationException e)Console.WriteLine(Failed to serialize.Reason:+e.Message);throw;finally fs.Close();FileStream fs1=new FileStream(Temp.dat,FileMode.Open);BinaryFormatt
15、er formatter1=new BinaryFormatter();try clone=(WeeklyLog)formatter1.Deserialize(fs1);/反序列化反序列化 catch(SerializationException e)Console.WriteLine(Failed to deserialize.Reason:+e.Message);throw;finally fs1.Close();return clone;周报是否相同?否附件是否相同?否客户端输出客户端输出www.ChinaSA.info原型管理器w定义原型管理器原型管理器(Prototype Manag
16、er)将多个原型对象存将多个原型对象存储在一个储在一个集合集合中供客户端使用,它是一个中供客户端使用,它是一个专门负责克专门负责克隆对象的工厂隆对象的工厂,其中,其中定义了一个集合定义了一个集合用于存储原型对用于存储原型对象,如果需要某个原型对象的一个克隆,可以通过复象,如果需要某个原型对象的一个克隆,可以通过复制集合中对应的原型对象来获得制集合中对应的原型对象来获得www.ChinaSA.info原型管理器w结构带带原型管理器的原型模式原型管理器的原型模式www.ChinaSA.info原型管理器w实现using System.Collections;class PrototypeManag
17、erHashtable ht=new Hashtable();/使用使用Hashtable存存储储原型原型对对象象 public PrototypeManager()ht.Add(A,new ConcretePrototypeA();ht.Add(B,new ConcretePrototypeB();public void Add(string key,Prototype prototype)ht.Add(key,prototype);public Prototype Get(string key)Prototype clone=null;clone=(Prototype)htkey).Clo
18、ne();/通通过过克隆方法克隆方法创创建新建新对对象象 return clone;www.ChinaSA.info原型模式的优缺点与适用环境w模式优点简化对象的创建过程简化对象的创建过程,通过复制一个已有实,通过复制一个已有实例可以例可以提高新实例的创建效率提高新实例的创建效率扩展性较好扩展性较好提供了提供了简化的创建结构简化的创建结构,原型模式中产品的,原型模式中产品的复制是通过封装在原型类中的克隆方法实现复制是通过封装在原型类中的克隆方法实现的,无须专门的工厂类来创建产品的,无须专门的工厂类来创建产品可以使用深克隆的方式可以使用深克隆的方式保存对象的状态保存对象的状态,以,以便在需要的时
19、候使用,可辅助实现撤销操作便在需要的时候使用,可辅助实现撤销操作www.ChinaSA.info原型模式的优缺点与适用环境w模式缺点需要为每一个类配备一个克隆方法需要为每一个类配备一个克隆方法,而且该,而且该克隆方法位于一个类的内部,当克隆方法位于一个类的内部,当对已有的类对已有的类进行改造时,需要修改源代码,违背了开闭进行改造时,需要修改源代码,违背了开闭原则原则在在实现深克隆时需要编写较为复杂的代码实现深克隆时需要编写较为复杂的代码,而且当对象之间存在多重的嵌套引用时,为而且当对象之间存在多重的嵌套引用时,为了实现深克隆,每一层对象对应的类都必须了实现深克隆,每一层对象对应的类都必须支持深
20、克隆,实现起来可能会比较麻烦支持深克隆,实现起来可能会比较麻烦www.ChinaSA.info原型模式的优缺点与适用环境w模式适用环境创建新对象成本较大创建新对象成本较大,新对象可以通过复制已,新对象可以通过复制已有对象来获得,如果是相似对象,则可以对其有对象来获得,如果是相似对象,则可以对其成员变量稍作修改成员变量稍作修改系统要保存对象的状态,而系统要保存对象的状态,而对象的状态变化很对象的状态变化很小小需要需要避免使用分层次的工厂类来创建分层次的避免使用分层次的工厂类来创建分层次的对象对象,并且类的实例对象只有一个或很少的几,并且类的实例对象只有一个或很少的几个组合状态,通过复制原型对象得到新实例可个组合状态,通过复制原型对象得到新实例可能比使用构造函数创建一个新实例更加方便能比使用构造函数创建一个新实例更加方便www.ChinaSA.infoENDEND