设计模式

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

2018-08-31  本文已影响0人  oO反骨仔Oo
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.一旦在类中使用到了别的类名,就意味着该类与其他类紧密地偶合在了一起。

上一篇下一篇

猜你喜欢

热点阅读