• 设计模式(五)—— 原型模式


    模式简介


    用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

    通俗来说,原型模式就是从一个对象,通过复制的手段去创建另外一个对象,而且不需要知道任何创建的细节。

    思考:这么做有什么好处?

    • 省略创建者类。例如在工厂方法中,客户端创建一个产品,必须调用相应工厂类中的方法获取产品实例。在原型模式中,原型本身提供Clone方法,因此原型的实例扮演了创建者和产品双重角色。
    • 减少创建实例带来的成本。这里所说的“成本”包括两个层面:系统性能的消耗创建实例的代码量。当初始化一个对象带来大量的性能消耗,需要创建多个实例且各个实例之间差别不大时,原型模式通过复制原型的方式减小系统性能的消耗。另一方面,当初始化对象需要大量繁杂的代码,使用原型模式避免了代码的重复。

    结构说明


    UML类图

    角色说明

    • Prototype

    抽象原型类。声明一个克隆自身的接口(抽象方法)

    • ConcretePrototype

    具体原型类。实现一个克隆自身的方法

    • Client

    让一个原型克隆自身从而创建一个新的对象

    示例分析


    下面我们来看一个创建颜色Color对象的示例:

    创建原型类Color(本示例省略了抽象原型类,改用ICloneable接口代替)

    class Color : ICloneable
    {
        private int red;
        private int green;
        private int yellow;
        public Color(int red,int green,int yellow)
        {
            this.red = red;
            this.green = green;
            this.yellow = yellow;
        }
        public object Clone()
        {
            Console.WriteLine($"Cloning color RGB: {red},{green},{yellow}");
            return this.MemberwiseClone() as Color;
        }
    }
    

    创建原型管理器ColorManager

    class ColorManager
    {
        Dictionary<string, Color> colors = new Dictionary<string, Color>();
        public Color this[string key]
        {
            get { return colors[key]; }
            set { colors.Add(key, value); }
        }
    
    }
    

    客户端向原型管理器注册,获取Color对象,以及动态注册原型

    static void Main(string[] args)
    {
        ColorManager colorManager = new ColorManager();
    
        //向原型管理器注册原型
        colorManager["red"] = new Color(255, 0, 0);
        colorManager["green"] = new Color(0, 255, 0);
        colorManager["yellow"] = new Color(0, 0, 255);
    
        //创建实例
        Color red = colorManager["red"].Clone() as Color;
    
        //动态注册原型
        Console.WriteLine("Start to register prototype : ");
        Console.WriteLine("Key : ");
        string key = Console.ReadLine();
        Console.WriteLine("RGB[example:255,54,0]:");
        string[] input = Console.ReadLine().Split(',');
        int[] rgb = Array.ConvertAll<string, int>(input, p => int.Parse(p));
        colorManager[key] = new Color(rgb[0], rgb[1], rgb[2]);
        Color myColor = colorManager[key].Clone() as Color;
    
        Console.ReadLine();
    }
    

    输出结果

    优缺点


    优点

    • 对客户隐藏了具体的产品类,减少了客户知道的产品的数目

    • 客户可以在运行时刻增加和删除产品

    • 改变值以指定新对象,例如通过为一个对象变量指定不同的值并注册为对象的原型

    • 改变结构以指定新对象

    • 减少子类的构造

    • 用类动态配置应用

    缺点

    • 每个Prototype子类都必须实现Clone操作,有时会比较困难

    浅拷贝与深拷贝


    浅拷贝

    拷贝一个对象时,仅拷贝对象的引用,拷贝的对象和源对象引用同一份实体。也就是说,改变其中一个对象会影响到另一个对象的状态。

    深拷贝

    拷贝一个对象时,不仅拷贝对象的引用,还将对象引用的值一同拷贝。这样拷贝的对象和源对象相互独立,其中一个改变不会影响另外一个对象。

    使用场景


    当一个系统应该独立于它的产品创建、构成和表示时,要使用Prototype模式;以及

    • 当要实例化的类是在运行时刻指定时;或者
    • 为了避免创建一个与产品类层次平行的工厂类层次时;或者
    • 当一个类的实例只能有几个不同状态组合中的一种时
  • 相关阅读:
    680. Valid Palindrome II【easy】
    125. Valid Palindrome【easy】
    459. Repeated Substring Pattern【easy】
    2. Trailing Zeros【easy】
    142. O(1) Check Power of 2【easy】
    181. Flip Bits【easy】
    183.Wood Cut【hard】
    61. Search for a Range【medium】
    关闭微软对win10的推送
    让未激活的win8.1不再跳出提示激活的窗口
  • 原文地址:https://www.cnblogs.com/Answer-Geng/p/9053390.html
Copyright © 2020-2023  润新知