设计模式三:原型模式(Prototype Pattern)

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

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

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

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

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

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

 类图:

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

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

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

        一、抽象原型角色(Prototype)

复制代码
//抽象原型角色:Prototype
abstractclass DrawPrototype
{
//需要绘制的图形名称、高和宽
publicstring DrawName{get;set;}

publicdouble Height { get; set; }

publicdouble Width { get; set; }

///<summary>
/// 对原型进行克隆
///</summary>
///<returns></returns>
publicabstract DrawPrototype DrawClone();
}
复制代码

        二、具体原型角色(ConcretePrototype)

复制代码
//具体原型角色:ConcretePrototype
class ConcreteDrawing : DrawPrototype
{
///<summary>
/// 实现原型模式的自我浅拷贝
///</summary>
///<returns></returns>
publicoverride DrawPrototype DrawClone()
{
return (DrawPrototype)this.MemberwiseClone();
}

///<summary>
/// 显示自身特性
///</summary>
publicvoid ShowInfo()
{
Console.WriteLine(DrawName
+""+ Height.ToString() +""+ Width.ToString());
}
}
复制代码

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

复制代码
//原型管理器
class DrawManager
{
//原型库
List<ConcreteDrawing> drawingList =new List<ConcreteDrawing>();

//添加原型到原型库
publicvoid AddDrawing(DrawPrototype cdraw)
{
drawingList.Add(cdraw);
}

//获取到对应名字的原型以供克隆副本
public ConcreteDrawing GetDrawing(string drawName)
{
return drawingList.FirstOrDefault(x => x.DrawName == drawName);
}
}
复制代码

        四、客户端角色(Client)

复制代码
//客户端:Client
class Program
{
staticvoid 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();
}
}
原文地址:https://www.cnblogs.com/jsping/p/2706788.html