第 6 章 Prototype 模式 -- 通过复制生成实例
2018-08-31 本文已影响0人
oO反骨仔Oo
image.png
Prototype 模式
特征:不指定类名的前提下创建实例。
示例
image.pngnamespace 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.pngPrototype:原型
用于定义复制现有实例来生成新实例的方法,对应 Product 抽象类(或接口)。
ConcretePrototype:具体的原型
负责实现 Prototype 所定义的方法,对应示例中的 MessageBox 类 和 UnderlinePen 类。
Client:使用者
调用方,对应示例中的 Manager 类。
要点 & 思路
1.不能或不希望根据类来生成实例,如:
(1)对象种类繁多,无法将其整合到一个类中;
(2)难以根据类来生成实例。如:WinForm 中用户通过一系列鼠标操作创建的类;
(3)解耦框架与生成的实例
相关模式
Flyweight 模式
使用 Prototype 模式可以生成一个与当前实例的状态完全相同的实例,而使用 Flyweight 模式可以在不同的地方使用同一个实例。
Memento 模式
使用 Prototype 模式可以生成一个与当前实例的状态完全相同的实例,而使用 Memento 模式可以保存当前实例的状态,以实现快照和撤销功能。
Composite 模式
Decorator 模式
Command 模式
备注
1.一旦在类中使用到了别的类名,就意味着该类与其他类紧密地偶合在了一起。