设计模式—原型模式
前言
在软件系统中,当创建一个类的实例很复杂时,并且还需要创建多个这样的实例时,如果使用关键字new去创建的话,会增加创建类的复杂度和耗费更多的内存空间,因为这样在内存中分配了多个一样的实例对象,然后采用工厂模式开创建系统的话,会随着产品类的不断增加导致子类的数量不断增多,反正增加了系统复杂度所以使用工厂模式不合适。
可以使用原型模式解决这一问题。只创建一个类实例对象,如果需要更多这样的实例,可以通过对原来对象的拷贝一份来创建,这一在内存中不需要创建多个相同的类实例,从而减少对内存的消耗
原型模式介绍
1)实际例子
使用原型模式的例子,比如细胞分裂的过程,一个细胞的有丝分裂产生两个相同的细胞;还有西游记中孙悟空变出后孙的本领和火影忍者中鸣人的隐分身忍术等。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 ///火影忍者中鸣人的影分身和孙悟空的的变都是原型模式 7 namespace ConsoleApplication1 8 { 9 /// <summary> 10 /// 孙悟空原型 11 /// </summary> 12 public abstract class MonkeyKingPrototype 13 { 14 public string Id { set; get; } 15 public MonkeyKingPrototype(string id) 16 { 17 this.Id = id; 18 } 19 20 // 克隆方法,即孙大圣说“变” 21 public abstract MonkeyKingPrototype Clone(); 22 } 23 24 /// <summary> 25 /// 创建具体原型 26 /// </summary> 27 public class ConcretePrototype : MonkeyKingPrototype 28 { 29 //public ConcretePrototype(string id) { }//报错 子类实例化时会先实例化父类的构造函数,如果没有指定的话会调用父类的无参构造方法,而此时父类中没有无参构造方法,所以会报错 30 public ConcretePrototype(string id) : base(id) { }//指定调用父类构造方法时,首选调用父类一个参数的构造方法 31 32 /// <summary> 33 /// 浅拷贝 34 /// </summary> 35 /// <returns></returns> 36 public override MonkeyKingPrototype Clone() 37 { 38 // 调用MemberwiseClone方法实现的是浅拷贝,另外还有深拷贝 39 return (MonkeyKingPrototype)this.MemberwiseClone(); 40 } 41 } 42 }
调用方法:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace ConsoleApplication1 7 { 8 class Program 9 { 10 static void Main(string[] args) 11 { 12 // 孙悟空 原型 13 MonkeyKingPrototype prototype = new ConcretePrototype("MongkeyKing"); 14 15 // 变一个 16 MonkeyKingPrototype prototype1 = prototype.Clone(); 17 Console.WriteLine("Clone1" + prototype1.Id); 18 19 // 变二个 20 MonkeyKingPrototype prototype2 = prototype.Clone(); 21 Console.WriteLine("Clone2" + prototype2.Id); 22 } 23 } 24 }
运行结果:
2)原型模式介绍
原型模式就是通过给出一个原型对象来指明索要创建的对象类型,然后用复制这个对象的方法来创建出更多的相同实例对象
3)原型模式分析
优点:
原型模式向客户隐藏了创建新实例的复杂性
原型模式运行动态增加或减少产品类
原型模式简化了实例的创建结构,工厂方法模式需要有一个与产品类等级结构相同的等级结构而原型模式不需要
产品类不需要事先确定产品的等级结构,因为原型模式使用与任何的等级结构
缺点:
每个类必须有一个克隆方法
配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不一定很容易,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候