目录
原型模式
引言
原型模式是一种特殊的创建型模式,当需要创建大量相同或相似的对象时,可以通过对一个已有的对象的复制获取更多对象。
定义
英文定义:"Specify the kind of objects to create using a prototypical instance,and create new objects by copying this prototype."。
中文定义:用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。
原型模式重要等级★★★★☆ 原型模式难度等级★★★☆☆
模式结构图
实例
邮件复制
实例描述
由于邮件对象包含的内容较多(如发送者、接收者、标题、内容、日期、附件等),某系统中现需要提供一个邮件复制功能,对于已经创建好的邮件对象,可以通过复制的方式创建一个新的邮件对象。
实例类图
代码实现
Email邮件类,ICloneanle接口为framework自带的,实现即可。除了附件外,其他属性都是值类型。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
class Email : ICloneable
{
private Attachment attachment;
private string sender;
private string receiver;
private string title;
private DateTime createDate;
private string content;
public string Content
{
get
{
return content;
}
set
{
content = value;
}
}
public string Title
{
get
{
return title;
}
set
{
title = value;
}
}
public string Receiver
{
get
{
return receiver;
}
set
{
receiver = value;
}
}
public string Sender
{
get
{
return sender;
}
set
{
sender = value;
}
}
internal Attachment Attachment
{
get
{
return attachment;
}
set
{
attachment = value;
}
}
public object Clone()
{
return this.MemberwiseClone();
}
public Email Copy()
{
Email emailClone = (Email)Clone();
emailClone.createDate = DateTime.Now;
return emailClone;
}
public Email()
{
createDate = DateTime.Now;
}
public void Display()
{
Console.WriteLine(string.Format("发件人:{0}\n{1}\n{2}\n收件人:{3}\n日期:{4}\n附件:{5}",
sender, title, content, receiver, createDate, attachment.Content)
);
}
}
Attachment附件类,该类主要是让邮件类中拥有一个引用类型。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
class Attachment
{
private string content;
public string Content
{
get
{
return content;
}
set
{
content = value;
}
}
public void Download()
{
Console.WriteLine("下载附件:" + Content);
}
}
编写测试类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static void Main(string[] args)
{
Email email = new Email();
Attachment attachment = new Attachment();
attachment.Content = "附件A";
email.Attachment = attachment;
email.Sender = "川";
email.Title = "离职申请";
email.Content = "这点钱很难给您办事啊。";
email.Receiver = "老板";
Thread.Sleep(3000);
Email emailClone = email.Copy();
emailClone.Content = "老板,刚才发错了!";
email.Display();
Console.WriteLine("---------------");
emailClone.Display();
Console.ReadKey();
}
}
运行结果
从结果上可以看到,邮件内容和邮件日期(线程睡眠了3秒)改变了,其他没有改变。创建非常方便。
模式扩展
深克隆和潜克隆
克隆可以分为深克隆和浅克隆,本例中邮件的附件就是浅克隆。由于该原型模式使用的是浅克隆,因此附件其实是同一个附件,如果修改克隆中的附件,远邮件中附件也会改变,如果有需要,应当将其深克隆
1.浅克隆
在浅克隆中,被复制的对象所有的普通成员变量(值对象)都具有与原来的对象相同的值,而所有的对其他对象的引用(引用对象)仍然指向原来的对象。简单来说,浅克隆仅仅复制对象的值成员,而引用成员只复制引用,复制出来的引用对象还是指向相同的对象。大部分语言如C#,JAVA都有很好的支持。无需自己编写代码。
2.深克隆:
深克隆不仅复制对象的值成员,对象包含的引用也被复制。深克隆可能需要编写复杂的代码,可以使用序列化对象的方式实现深克隆。
原型管理
原型模式的一种改进形式是带原型管理器的原型模式,原型管理器的作用与工厂相似,其中定义了一个集合用于存储原型对象,如果需要某个对象的一个克隆,可以通过复制集合中的对应原型对象来获得,其结构图如下所示。
总结
模式优点
1)对于一些复杂对象的创建,复制原型对象可能比使用构造函数创建实例更方便。
2)可以动态增加或减少产品类。由于创建产品类实例的方法是产品内部具有的,所以新增产品对整个结构没有影响。
3)可以利用深克隆的方式保存对象的状态,
模式缺点
1)需要为每一个类配备一个克隆方法,而且这个克隆方法需要对类的功能进行通盘考虑,这对全新的类来说不是很难,但对已有的类进行改造时,不一定是件容易的事,必须修改其源代码,违背了“开闭原则”。
2)实现深克隆时可能需要编写复杂的代码。