分享

【C#设计模式-原型模式】

 鸿枫nh 2017-02-21

原型模式定义和结构:

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。


创建型模式中一个比较特殊的模式-原型模式,有个最大的特点是克隆一个现有的对象,这个克隆的结果有2种,一种是浅度复制,另一种是深度复制。

创建型模式一般是用来创建一个新的对象,然后我们使用这个对象完成一些对象的操作,我们通过原型模式可以快速的创建一个对象而不需要提供专门的new()操作就可以快速完成对象的创建,这无疑是一种非常有效的方式,快速的创建一个新的对象。

一.浅度复制:

先看原型模式的经典实现:定义一个接口, 用来表述所有的颜色对象接口

[csharp] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. /// <summary>  
  2.    /// 颜色接口  
  3.    /// </summary>  
  4.    public interface IColor  
  5.    {  
  6.        IColor Clone();  
  7.   
  8.        int Red { getset; }  
  9.        int Green { getset; }  
  10.        int Blue { getset; }  
  11.    }  
给出红色的具体实现代码:

[csharp] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. public class RedColor:IColor  
  2.    {  
  3.        public int Red { getset; }  
  4.        public int Green { getset; }  
  5.        public int Blue { getset; }  
  6.   
  7.        public IColor Clone()  
  8.        {  
  9.            return (IColor)this.MemberwiseClone();   
  10.        }   
  11.    }  
具体的测试代码如下:

[csharp] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. static void Main(string[] args)  
  2.        {  
  3.            IColor color = new RedColor();  
  4.            color.Red = 255;  
  5.            Console.WriteLine("color -red " + color.Red); //225  
  6.            IColor color1 = color.Clone();  
  7.            color1.Red = 224;  
  8.            Console.WriteLine("color1-red " + color1.Red);//224  
  9.            Console.WriteLine("color -red " + color.Red); //225  
  10.        }  

运行结果如下:


可以发现:在我们修改color1对象的Red属性值,没有对color的属性参生影响。

即对象副本的修改不会影响对象本身的状态,

二.深度复制:

深复制考虑的情况相对来说就会比较复杂,因为有可能对象是之间有继承关系或者引用关系的时候,可能我们深复制的时候就需要注意.

一般来说深复制一方面可以采用种简单的深复制对象的时候的方案,还可以通过序列化的形式来进行对象的复制。

下面通过序列化的形式来实现原型模式:

[csharp] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5.   
  6. namespace ConsoleApplication4  
  7. {  
  8.     /// <summary>  
  9.     /// 颜色接口  
  10.     /// </summary>  
  11.     public interface IColor  
  12.     {  
  13.         IColorDemo Clone();  
  14.   
  15.         int Red { getset; }  
  16.         int Green { getset; }  
  17.         int Blue { getset; }  
  18.         Factroy f{get;set;}  
  19.     }  
  20.   
  21.     /// <summary>  
  22.     /// 生产颜色的工厂信息  
  23.     /// </summary>  
  24.     [Serializable]  
  25.     public class Factroy  
  26.     {  
  27.         public string name { getset; }  
  28.     }  
  29. }  
[csharp] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5.   
  6. namespace ConsoleApplication4  
  7. {  
  8.     /// <summary>  
  9.     /// 颜色  
  10.     /// </summary>  
  11.     [Serializable]  
  12.     public class RedColor:IColor  
  13.     {  
  14.         public int Red { getset; }  
  15.         public int Green { getset; }  
  16.         public int Blue { getset; }  
  17.         public Factroy f { getset; }  
  18.   
  19.         public IColor Clone()  
  20.         {  
  21.             SerializableHelper s = new SerializableHelper();  
  22.             string target = s.Serializable(this);  
  23.             return s.Derializable<IColor>(target);   
  24.         }   
  25.     }  
  26. }  
[csharp] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. /// <summary>  
  2.    /// 序列化和反序列化辅助类  
  3.    /// </summary>  
  4.    public class SerializableHelper  
  5.    {  
  6.        public string Serializable(object target)  
  7.        {  
  8.            using (MemoryStream stream = new MemoryStream())  
  9.            {  
  10.                new BinaryFormatter().Serialize(stream, target);  
  11.   
  12.                return Convert.ToBase64String(stream.ToArray());  
  13.            }  
  14.        }  
  15.   
  16.        public object Derializable(string target)  
  17.        {  
  18.            byte[] targetArray = Convert.FromBase64String(target);  
  19.   
  20.            using (MemoryStream stream = new MemoryStream(targetArray))  
  21.            {  
  22.                return new BinaryFormatter().Deserialize(stream);  
  23.            }  
  24.        }  
  25.   
  26.        public T Derializable<T>(string target)  
  27.        {  
  28.            return (T)Derializable(target);  
  29.        }  
  30.    }  
[csharp] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. static void Main(string[] args)  
  2.         {  
  3.             IColor color = new RedColor();  
  4.             color.Red = 255;  
  5.             color.f = new Factroy() { name="湖北工厂" };  
  6.             Console.WriteLine("color - Factroy:" + color.f.name);  //湖北工厂  
  7.   
  8.             IColor color1 = color.Clone();  
  9.             color1.Red = 234;  
  10.             color1.f.name = "北京工厂";  
  11.             Console.WriteLine("color1- Factroy:" + color1.f.name); //北京工厂  
  12.             Console.WriteLine("color - Factroy:" + color.f.name);  //湖北工厂  
  13.             Console.Read();  
  14.         }  
程序的运行结果如下:


结论:通过序列化和反序列化形成新的对象。其实只要是项目中要使用原型模式进行对象复制的情况下,都可以通过序列化的形式来进行深复制。

关于深度复制和浅度复制的区别可以参考http://blog.csdn.net/heyangyi_19940703/article/details/51241081

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多