wordpress网站怎么百度的到,书店网站建设方案,天津专业做标书,杭州有专业做网站小型服装厂吗总目录 前言
在软件系统中#xff0c;当创建一个类的实例的过程很昂贵或很复杂#xff0c;并且我们需要创建多个这样类的实例时#xff0c;如果我们用new操作符去创建这样的类实例#xff0c;这未免会增加创建类的复杂度和耗费更多的内存空间#xff0c;因为这样在内存中…总目录 前言
在软件系统中当创建一个类的实例的过程很昂贵或很复杂并且我们需要创建多个这样类的实例时如果我们用new操作符去创建这样的类实例这未免会增加创建类的复杂度和耗费更多的内存空间因为这样在内存中分配了多个一样的类实例对象然后如果采用工厂模式来创建这样的系统的话随着产品类的不断增加导致子类的数量不断增多反而增加了系统复杂程度所以在这里使用工厂模式来封装类创建过程并不合适然而原型模式可以很好地解决这个问题因为每个类实例都是相同的当我们需要多个相同的类实例时没必要每次都使用new运算符去创建相同的类实例对象此时我们一般思路就是想——只创建一个类实例对象如果后面需要更多这样的实例可以通过对原来对象拷贝一份来完成创建这样在内存中不需要创建多个相同的类实例从而减少内存的消耗和达到类实例的复用。 然而这个思路正是原型模式的实现方式。 1 基本介绍
原型模式就是通过复制已有对象来创建新对象而避免重复进行初始化操作生产多个克隆对象。本质通过拷贝这些原型对象创建新的对象。原型模式中的2个角色 Prototype原型类声明一个Clone自身的接口ConcretePrototype具体原型类实现一个Clone自身的操作使用Clone方法完成对象的创建 浅拷贝和深拷贝 浅拷贝通过this.MemberWiseClone()对实例的值类型进行拷贝包含string类型对引用类型只拷贝了引用。浅拷贝只对值类型成员进行复制对于引用类型只是复制了其引用并不复制其对象。执行浅拷贝创建的新对象与原来对象共享成员改变一个对象另外一个对象的成员也会改变。 深拷贝需要通过反射和序列化来实现执行深拷贝创建的新对象和原来对象不会共享任何东西改变一个对象对另外一个对象没有任何影响
2 使用场景
对象在创建new时消耗资源过多或繁琐耗时。
本质就是在对象的构造函数中有耗时长或者占用系统资源多的情况
使用原型模式进行复制对象时可以省去这些耗时耗力的操作直接获得对象的具体实例。
最常见的使用场景之一就是对象历史节点的保存比如在对对象进行操作一次后进行一次复制保存当前状态恢复到某一历史状态可实现撤销操作。
3 实现方式
在现实生活中也有很多原型设计模式的例子例如细胞分裂的过程一个细胞的有丝分裂产生两个相同的细胞还有西游记中孙悟空变出后孙的本领和火影忍者中鸣人的隐分身忍术等。
1 抽象的原型类定义一个复制自己的方法 public abstract class Prototype{//Id 值类型public int Id { get; set; }//Message string类型public string Message { get; set; }//NameList 引用类型public Liststring NameList { get; set; } new Liststring();//构造函数public Prototype(){}//复制的方法public abstract Prototype Clone();}2 具体的原型类需要实现复制自己的方法 //具体的原型类public class ConcretePrototype : Prototype{public ConcretePrototype() : base(){}public override Prototype Clone(){// 调用MemberwiseClone方法实现的是浅拷贝另外还有深拷贝return (Prototype)this.MemberwiseClone();}}3 客户端调用 public static void Main(string[] args){// 首先创建一个原型类并给相关属性赋值Prototype concretePrototype new ConcretePrototype();concretePrototype.Id 1;concretePrototype.Message 消息AAA;concretePrototype.NameList.Add(Jack);concretePrototype.NameList.Add(Marks);Console.WriteLine($Id{concretePrototype.Id});Console.WriteLine($Message{concretePrototype.Message});Console.WriteLine(NameList);foreach ( string item in concretePrototype.NameList){Console.WriteLine($Name{item});}Console.WriteLine(\r\n);// 然后通过 实现后的原型类 去 复制出一个对象// 然后给复制出的对象赋值验证当前浅拷贝对于值类型和引用类型的影响Prototype concretePrototype2 concretePrototype.Clone();concretePrototype2.Id 2;concretePrototype2.Message 消息BBB;concretePrototype2.NameList[1] Jack Ma;Console.WriteLine($复制的对象 Id{concretePrototype2.Id});Console.WriteLine($复制的对象 Message{concretePrototype2.Message});Console.WriteLine(复制的对象 NameList);foreach (string item in concretePrototype2.NameList){Console.WriteLine($Name{item});}Console.WriteLine(\r\n);Console.WriteLine(更改了复制对象属性的值对比值类型和类型类型的变化);Console.WriteLine($Id{concretePrototype.Id});Console.WriteLine($Message{concretePrototype.Message});Console.WriteLine(NameList);foreach (string item in concretePrototype.NameList){Console.WriteLine($Name{item});}Console.ReadLine();}通过这个实例可以看出浅复制对值类型和string进行全盘拷贝对引用类型除string只拷贝了引用地址。
4 深拷贝的实现方式 //原型类[Serializable]public abstract class Prototype{//Id 值类型public int Id { get; set; }//Message string类型public string Message { get; set; }//NameList 引用类型public Liststring NameList { get; set; } new Liststring();//构造函数public Prototype(){}//复制的方法public abstract Prototype Clone();}//具体的原型类[Serializable]public class ConcretePrototype : Prototype{public ConcretePrototype() : base(){}// 实现深拷贝public override Prototype Clone(){//创建一个内存流MemoryStream ms new MemoryStream();//创建一个二进制序列化对象BinaryFormatter bf new BinaryFormatter();//将当前对象序列化写入ms内存流中bf.Serialize(ms, this);//设置流读取的位置ms.Position 0;//将流反序列化为Object对象return bf.Deserialize(ms) as Prototype;}}执行深拷贝创建的新对象和原来对象不会共享任何东西改变一个对象对另外一个对象没有任何影响
4 优缺点分析 优点 原型模式向客户隐藏了创建新实例的复杂性原型模式允许动态增加或较少产品类。原型模式简化了实例的创建结构工厂方法模式需要有一个与产品类等级结构相同的等级结构而原型模式不需要这样。产品类不需要事先确定产品的等级结构因为原型模式适用于任何的等级结构 缺点 每个类必须配备一个克隆方法配备克隆方法需要对类的功能进行通盘考虑这对于全新的类不是很难但对于已有的类不一定很容易特别当一个类引用不支持串行化的间接对象或者引用含有循环结构的时候。 结语
希望以上内容可以帮助到大家如文中有不对之处还请批评指正。 参考资料 c#中原型模式详解 C#设计模式6-原型模式