四个角色:抽象原型角色(Prototype)、具体原型角色(ConcretePrototype)、原型管理器角色(PrototypeManager)、客户端角色(Client)
抽象原型角色(Prototype):定义原型的克隆方法接口
具体原型角色(ConcretePrototype):实现原型具体的克隆方法
原型管理器角色(PrototypeManager):负责具体原型的增、删、查和原型容器。
客户端角色(Client):实例化多个原型、并且通过原型的克隆接口克隆多个子对象。
实现思路:首先实例化多个原型A、B、C、D,然后在客户端调用A原型的Clone接口即可获取到A原型的克隆子对象,并且可以重新设置这个克隆子对象的值。
类图:
应用场景:在Silverlight中的制作一个绘制工程图的工具箱,里面可以有很多直线选择器、圆形选择器、矩形选择器,我们点一次这个工具箱中得选择器,则绘制一个相应的图。
分析:如果要绘制上万个圆形,不可能去实例一万个圆形对象,在这里我们使用原型模式,设置好默认的原型属性,每次拖动的时候,实际上通过其原型类浅拷贝一个副本对象即可。
下面我们在控制台程序去演示一下如何使用Prototype Pattern:
一、抽象原型角色(Prototype)
- //抽象原型角色:Prototype
- abstract class DrawPrototype
- {
- //需要绘制的图形名称、高和宽
- public string DrawName{get;set;}
- public double Height { get; set; }
- public double Width { get; set; }
- /// <summary>
- /// 对原型进行克隆
- /// </summary>
- /// <returns></returns>
- public abstract DrawPrototype DrawClone();
- }
二、具体原型角色(ConcretePrototype)
- //具体原型角色:ConcretePrototype
- class ConcreteDrawing : DrawPrototype
- {
- /// <summary>
- /// 实现原型模式的自我浅拷贝
- /// </summary>
- /// <returns></returns>
- public override DrawPrototype DrawClone()
- {
- return (DrawPrototype)this.MemberwiseClone();
- }
- /// <summary>
- /// 显示自身特性
- /// </summary>
- public void ShowInfo()
- {
- Console.WriteLine(DrawName + " " + Height.ToString() + " " + Width.ToString());
- }
- }
三、原型管理器角色(PrototypeManager)
- //原型管理器
- class DrawManager
- {
- //原型库
- List<ConcreteDrawing> drawingList = new List<ConcreteDrawing>();
- //添加原型到原型库
- public void AddDrawing(DrawPrototype cdraw)
- {
- drawingList.Add(cdraw);
- }
- //获取到对应名字的原型以供克隆副本
- public ConcreteDrawing GetDrawing(string drawName)
- {
- return drawingList.FirstOrDefault(x => x.DrawName == drawName);
- }
- }
四、客户端角色(Client)
- //客户端:Client
- class Program
- {
- static void Main(string[] args)
- {
- //初始化绘画管理工具
- DrawManager drawManager = new DrawManager();
- //初始化矩形、圆形、梯形、直线的原型实体以供后面拖出来使用
- drawManager.AddDrawing(new ConcreteDrawing() { DrawName = "Rectangle", Width = 100, Height = 100 });
- drawManager.AddDrawing(new ConcreteDrawing() { DrawName = "Round", Width = 80, Height = 80 });
- drawManager.AddDrawing(new ConcreteDrawing() { DrawName = "Trapezoidal", Width = 50, Height = 50 });
- drawManager.AddDrawing(new ConcreteDrawing() { DrawName = "Line", Width = 100, Height = 1 });
- //调用原型的Clone方法获取浅拷贝对象
- ConcreteDrawing rect1 = (ConcreteDrawing)drawManager.GetDrawing("Rectangle").DrawClone();
- rect1.Height = 197;
- rect1.ShowInfo();
- ConcreteDrawing rect2 = (ConcreteDrawing)drawManager.GetDrawing("Rectangle").DrawClone();
- rect2.Width = 112;
- rect2.ShowInfo();
- ConcreteDrawing rect3 = (ConcreteDrawing)drawManager.GetDrawing("Rectangle").DrawClone();
- rect3.ShowInfo();
- ConcreteDrawing line = (ConcreteDrawing)drawManager.GetDrawing("Line").DrawClone();
- line.ShowInfo();
- Console.ReadLine();
- }
- }
如需源码请点击 PrototypePattern.rar 下载。
本文转自程兴亮 51CTO博客,原文链接:http://blog.51cto.com/chengxingliang/826948