四个角色:抽象原型角色(Prototype)、具体原型角色(ConcretePrototype)、原型管理器角色(PrototypeManager)、客户端角色(Client)

        抽象原型角色(Prototype):定义原型的克隆方法接口

        具体原型角色(ConcretePrototype):实现原型具体的克隆方法

        原型管理器角色(PrototypeManager):负责具体原型的增、删、查和原型容器。

        客户端角色(Client):实例化多个原型、并且通过原型的克隆接口克隆多个子对象。

实现思路:首先实例化多个原型A、B、C、D,然后在客户端调用A原型的Clone接口即可获取到A原型的克隆子对象,并且可以重新设置这个克隆子对象的值。

 类图:

应用场景:在Silverlight中的制作一个绘制工程图的工具箱,里面可以有很多直线选择器、圆形选择器、矩形选择器,我们点一次这个工具箱中得选择器,则绘制一个相应的图。

分析:如果要绘制上万个圆形,不可能去实例一万个圆形对象,在这里我们使用原型模式,设置好默认的原型属性,每次拖动的时候,实际上通过其原型类浅拷贝一个副本对象即可。

        下面我们在控制台程序去演示一下如何使用Prototype Pattern:

        一、抽象原型角色(Prototype)

 

 
   
  1. //抽象原型角色:Prototype 
  2. abstract class DrawPrototype 
  3.     //需要绘制的图形名称、高和宽 
  4.     public string DrawName{get;set;} 
  5.  
  6.     public double Height { get; set; } 
  7.  
  8.     public double Width { get; set; } 
  9.  
  10.     /// <summary> 
  11.     /// 对原型进行克隆 
  12.     /// </summary> 
  13.     /// <returns></returns
  14.     public abstract DrawPrototype DrawClone(); 

        二、具体原型角色(ConcretePrototype)

 

 
   
  1. //具体原型角色:ConcretePrototype 
  2.  class ConcreteDrawing : DrawPrototype 
  3.  { 
  4.      /// <summary> 
  5.      /// 实现原型模式的自我浅拷贝 
  6.      /// </summary> 
  7.      /// <returns></returns
  8.      public override DrawPrototype DrawClone() 
  9.      { 
  10.          return (DrawPrototype)this.MemberwiseClone(); 
  11.      } 
  12.  
  13.      /// <summary> 
  14.      /// 显示自身特性 
  15.      /// </summary> 
  16.      public void ShowInfo() 
  17.      { 
  18.          Console.WriteLine(DrawName + " " + Height.ToString() + " " + Width.ToString()); 
  19.      } 
  20.  } 

        三、原型管理器角色(PrototypeManager)

 

 
   
  1. //原型管理器 
  2. class DrawManager 
  3.     //原型库 
  4.     List<ConcreteDrawing> drawingList = new List<ConcreteDrawing>(); 
  5.  
  6.     //添加原型到原型库 
  7.     public void AddDrawing(DrawPrototype cdraw) 
  8.     { 
  9.         drawingList.Add(cdraw); 
  10.     } 
  11.  
  12.     //获取到对应名字的原型以供克隆副本 
  13.     public ConcreteDrawing GetDrawing(string drawName) 
  14.     { 
  15.         return drawingList.FirstOrDefault(x => x.DrawName == drawName);     
  16.     } 

        四、客户端角色(Client)

 

 
   
  1. //客户端:Client 
  2. class Program 
  3.     static void Main(string[] args) 
  4.     { 
  5.         //初始化绘画管理工具 
  6.         DrawManager drawManager = new DrawManager(); 
  7.         //初始化矩形、圆形、梯形、直线的原型实体以供后面拖出来使用 
  8.         drawManager.AddDrawing(new ConcreteDrawing() { DrawName = "Rectangle", Width = 100, Height = 100 }); 
  9.         drawManager.AddDrawing(new ConcreteDrawing() { DrawName = "Round", Width = 80, Height = 80 }); 
  10.         drawManager.AddDrawing(new ConcreteDrawing() { DrawName = "Trapezoidal", Width = 50, Height = 50 }); 
  11.         drawManager.AddDrawing(new ConcreteDrawing() { DrawName = "Line", Width = 100, Height = 1 }); 
  12.  
  13.         //调用原型的Clone方法获取浅拷贝对象 
  14.         ConcreteDrawing rect1 = (ConcreteDrawing)drawManager.GetDrawing("Rectangle").DrawClone(); 
  15.         rect1.Height = 197; 
  16.         rect1.ShowInfo();  
  17.         ConcreteDrawing rect2 = (ConcreteDrawing)drawManager.GetDrawing("Rectangle").DrawClone(); 
  18.         rect2.Width = 112; 
  19.         rect2.ShowInfo();  
  20.         ConcreteDrawing rect3 = (ConcreteDrawing)drawManager.GetDrawing("Rectangle").DrawClone(); 
  21.         rect3.ShowInfo(); 
  22.  
  23.         ConcreteDrawing line = (ConcreteDrawing)drawManager.GetDrawing("Line").DrawClone(); 
  24.         line.ShowInfo(); 
  25.  
  26.         Console.ReadLine(); 
  27.     } 

        如需源码请点击 PrototypePattern.rar 下载。