• 极速理解设计模式系列:4.原型模式(Prototype Pattern)


    四个角色:抽象原型角色(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 下载。

  • 相关阅读:
    win7 下加载MSCOMCTL.OCX
    getGLES1ExtensionString: Could not find GLES 1.x config!
    IUnknown(TVarData(Params[0]).VPointer) as Range
    win8 VB6打开提示MSCOMCTL.ocx未注册
    服务端接口处理流任务要如何返回?
    flink之kafka生产和消费实战-将生产数据存放到mongodb中
    初识doris的那些基本概念
    bash常见用法
    sonar p3c规则配置
    sonar之gitlab ci 在gradle项目的实践(汉化、branch、 commit提交评论)
  • 原文地址:https://www.cnblogs.com/chengxingliang/p/2155568.html
Copyright © 2020-2023  润新知