zoukankan      html  css  js  c++  java
  • 设计模式——原型模式

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


    工作原理:将一个原型对象传给要发动创建的对象(即客户端对象),这个要发动创建的对象通过请求原型对象复制自己来实现创建过程

    创建新对象(也称为克隆对象)的工厂就是原型类自身,工厂方由负责复制原型对象的克隆方法来实现
    通过克隆方法所创建的对象是全新的对象,它们在内存中拥有新的地址,每一个克隆对象都是独立
    通过不同的方式对克隆对象进行修改以后,可以得到一系列相似但不完全相同的对象
     
    • 当一个系统独立于它的产品创建,构成和表示时,要使用原型模式。
    • 当要实例化的类是在运行时刻指定的,例如通过动态装载。
    • 为了避免创建一个与产品类层次平行的工厂类层次。
    • 当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们,可能比每次用合适的状态手工实例化方便些

    Prototype     声明一个克隆自身的接口

    ConcretePrototype     实现一个克隆自身的操作

    Client    让一个原型克隆自身从而创建新的对象

    浅克隆与深克隆

    浅克隆(Shallow Clone):当原型对象被复制时,只复制它本身和其中包含的值类型的成员变量,而引用类型的成员变量并没有复制
    深克隆(Deep Clone):除了对象本身被复制外,对象所包含的所有成员变量也将被复制
     

    浅度复制(Shallow Copy):将原来对象中的所有字段逐个复制到一个新对象,如果字段是值类型,则简单地复制一个副本到新对象,改变新对象的值类型字段不会影响原对象;如果字段是引用类型,则复制的是引用,改变目标对象中引用类型字段的值将会影响原对象。

    深度复制(Deep Copy):与浅复制不同之处在于对引用类型的处理,深复制将新对象中引用类型字段指向复制过的新对象,改变新对象中引用的任何对象,不会影响到原来的对象中对应字段的内容。

    .浅度复制

    先看原型模式的经典实现:定义一个接口, 用来表述所有的颜色对象接口
     
     1 /// <summary>  
     2    /// 颜色接口  
     3    /// </summary>  
     4    public interface IColor  
     5    {  
     6        IColor Clone();  
     7   
     8        int Red { get; set; }  
     9        int Green { get; set; }  
    10        int Blue { get; set; }  
    11    }  

    给出红色的具体实现代码:

     1 public class RedColor:IColor  
     2    {  
     3        public int Red { get; set; }  
     4        public int Green { get; set; }  
     5        public int Blue { get; set; }  
     6   
     7        public IColor Clone()  
     8        {  
     9            return (IColor)this.MemberwiseClone();   
    10        }   
    11    }  

    测试代码

     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        }  

    二.深度复制:

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

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

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

     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 { get; set; }  
    16         int Green { get; set; }  
    17         int Blue { get; set; }  
    18         Factroy f{get;set;}  
    19     }  
    20   
    21     /// <summary>  
    22     /// 生产颜色的工厂信息  
    23     /// </summary>  
    24     [Serializable]  
    25     public class Factroy  
    26     {  
    27         public string name { get; set; }  
    28     }  
    29 }  
     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 { get; set; }  
    15         public int Green { get; set; }  
    16         public int Blue { get; set; }  
    17         public Factroy f { get; set; }  
    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 }  
     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    }  
     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         }  

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

    学习于   https://blog.csdn.net/heyangyi_19940703/article/details/51241432

  • 相关阅读:
    【WP8】关于类库本地化问题
    【WP8】富文本功能实现
    【WP8】换肤功能的实现
    【WP8】图片缓存控件
    【WP8】图片压缩处理
    【WP8】让TextBox文本支持滑动(Scroll)
    <正则吃饺子> :关于Guava中 Joiner 和 Splitter 的简单使用
    <正则吃饺子> :关于前端往后端传递布尔值参数的问题
    <正则吃饺子>:关于使用powerDesign连接oracle数据库,导出数据表结构(ER图吧)
    <正则吃饺子>:关于集合的简单整理总结
  • 原文地址:https://www.cnblogs.com/cwmizlp/p/9141274.html
Copyright © 2011-2022 走看看