设计模式——原型模式

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


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

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

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

原文地址:https://www.cnblogs.com/cwmizlp/p/9141274.html