美文网首页设计模式
第 6 章 Prototype 模式 -- 通过复制生成实例

第 6 章 Prototype 模式 -- 通过复制生成实例

作者: oO反骨仔Oo | 来源:发表于2018-08-31 18:28 被阅读0次
    image.png

    Prototype 模式

    特征:不指定类名的前提下创建实例。

    示例

    image.png
    namespace PrototypePattern
    {
        /// <summary>
        /// 产品
        /// </summary>
        internal abstract class Product
        {
            /// <summary>
            /// 使用
            /// </summary>
            /// <param name="s"></param>
            public abstract void Use(string s);
    
            /// <summary>
            /// 克隆
            /// </summary>
            /// <returns></returns>
            public Product Clone()
            {
                return (Product) MemberwiseClone();
            }
        }
    }
    
    using System.Collections.Generic;
    
    namespace PrototypePattern
    {
        /// <summary>
        /// 管理者
        /// </summary>
        internal class Manager
        {
            private readonly Dictionary<string, Product> _showCase = new Dictionary<string, Product>();
    
            /// <summary>
            /// 注册
            /// </summary>
            /// <param name="name"></param>
            /// <param name="product"></param>
            public void Register(string name, Product product)
            {
                _showCase.Add(name, product);
            }
    
            /// <summary>
            /// 创建
            /// </summary>
            /// <param name="productName"></param>
            /// <returns></returns>
            public Product Create(string productName)
            {
                return _showCase[productName].Clone();
            }
        }
    }
    
    using System;
    
    namespace PrototypePattern
    {
        /// <summary>
        /// 对话框
        /// </summary>
        internal class MessageBox : Product
        {
            private readonly char _decochar;
    
            public MessageBox(char decochar)
            {
                _decochar = decochar;
            }
    
            public override void Use(string s)
            {
                var length = s.Length;
                for (var i = 0; i < length + 4; i++)
                {
                    Console.Write(_decochar);
                }
    
                Console.WriteLine();
                Console.Write(_decochar + " " + s + " " + _decochar);
                Console.WriteLine();
    
                for (var i = 0; i < length + 4; i++)
                {
                    Console.Write(_decochar);
                }
    
                Console.WriteLine();
            }
        }
    }
    
    using System;
    
    namespace PrototypePattern
    {
        /// <summary>
        /// 下拉钢笔线
        /// </summary>
        internal class UnderlinePen : Product
        {
            private readonly char _ulchar;
    
            public UnderlinePen(char ulchar)
            {
                _ulchar = ulchar;
            }
    
            public override void Use(string s)
            {
                var length = s.Length;
                Console.WriteLine($"\"{s}\"");
                Console.WriteLine();
    
                for (var i = 0; i < length; i++)
                {
                    Console.Write(_ulchar);
                }
    
                Console.WriteLine();
            }
        }
    }
    
    using System;
    
    namespace PrototypePattern
    {
        internal class Program
        {
            private static void Main(string[] args)
            {
                var manager = new Manager();
                var upen = new UnderlinePen('~');
                var mbox = new MessageBox('*');
                var sbox = new MessageBox('/');
    
                manager.Register("strong message", upen);
                manager.Register("warning box", mbox);
                manager.Register("slash box", sbox);
    
                var p1 = manager.Create("strong message");
                p1.Use("Hello, world.");
                Console.WriteLine();
    
                var p2 = manager.Create("warning box");
                p2.Use("Hello, world.");
                Console.WriteLine();
    
                var p3 = manager.Create("slash box");
                p3.Use("Hello, world.");
                Console.WriteLine();
    
                Console.Read();
            }
        }
    }
    
    image.png

    角色梳理

    image.png

    Prototype:原型

    用于定义复制现有实例来生成新实例的方法,对应 Product 抽象类(或接口)。

    ConcretePrototype:具体的原型

    负责实现 Prototype 所定义的方法,对应示例中的 MessageBox 类 和 UnderlinePen 类。

    Client:使用者

    调用方,对应示例中的 Manager 类。

    要点 & 思路

    1.不能或不希望根据类来生成实例,如:
    (1)对象种类繁多,无法将其整合到一个类中;
    (2)难以根据类来生成实例。如:WinForm 中用户通过一系列鼠标操作创建的类;
    (3)解耦框架与生成的实例

    相关模式

    Flyweight 模式

    使用 Prototype 模式可以生成一个与当前实例的状态完全相同的实例,而使用 Flyweight 模式可以在不同的地方使用同一个实例。

    Memento 模式

    使用 Prototype 模式可以生成一个与当前实例的状态完全相同的实例,而使用 Memento 模式可以保存当前实例的状态,以实现快照和撤销功能。

    Composite 模式

    Decorator 模式

    Command 模式

    备注

    1.一旦在类中使用到了别的类名,就意味着该类与其他类紧密地偶合在了一起。

    相关文章

      网友评论

        本文标题:第 6 章 Prototype 模式 -- 通过复制生成实例

        本文链接:https://www.haomeiwen.com/subject/ofjewftx.html