设计模式(五)原型

发布时间 2023-09-08 10:23:49作者: 冬先生

一、定义

使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象。原型模式是一种创建型模式。

二、描述

包含以下三个角色:
1、Prototype(抽象原型类):它是声明克隆方法的接口,是所有具体原型类的公共父类,可以是抽象类也可以是接口,甚至可以是具体实现类。
2、ConcretePrototype(具体原型类):它实现在抽象原型类中声明的克隆方法,在克隆方法中返回自己的一个克隆对象。
3、Client(客户类):在客户类中,让一个原型对象克隆自身从而创建一个新的对象,只需要直接实例化或通过工厂方法等方式创建一个原型对象,再通过调用该对象的克隆方法即可得到多个相同的对象。由于客户类针对抽象原型类Prototype编程,因此用户可以根据需要选择具体原型类,系统具有较好的可扩展性,增加或更换具体原型类都很方便。

三、例子

X公司在使用OA系统时发现,某些岗位员工的每周周报及其相似,为了提高写周报的效率,大家迫切希望有一种功能可以快速创建相同或者相似的周报,包括附件,使用原型模式对周报创建模块进行改进。WeeklyLog、Attachment:周报类、附件类,实际业务较为复杂,示例简化只列出部分属性

public class WeeklyLog
{
    public string Name { get; set; }
    public string Date { get; set; }
    public string Content { get; set; }
    public Attachment Attachment { get; set; }

    public WeeklyLog Clone()
    {
        return this.MemberwiseClone() as WeeklyLog;
    }
    public WeeklyLog CloneDeep()
    {
        return JsonSerializer.Deserialize<WeeklyLog>(JsonSerializer.Serialize(this));
    }
}
public class Attachment
{
    public string Name { get; set; }
}

Program:测试代码

Console.WriteLine("浅克隆");
WeeklyLog log_previous, log_new;
log_previous = new WeeklyLog();
log_previous.Attachment = new Attachment();
log_new = log_previous.Clone();
Console.WriteLine("周报是否相同:{0}", (log_previous == log_new ? "是" : "否"));
Console.WriteLine("附件是否相同:{0}", (log_previous.Attachment == log_new.Attachment ? "是" : "否"));

Console.WriteLine("深克隆");
log_new = log_previous.CloneDeep();
Console.WriteLine("周报是否相同:{0}", (log_previous == log_new ? "是" : "否"));
Console.WriteLine("附件是否相同:{0}", (log_previous.Attachment == log_new.Attachment ? "是" : "否"));
Console.ReadLine();

深克隆有很多种方法:序列化、二进制流、反射等。

三、总结