设计模式之原型模式
1、类图
实例类图
2、创建项目
……………………………………
3、 新建周报类WeeklyLog:充当原型角色,Clone()方法为克隆方法,用于实现原型对象的克隆,Attachmentch充当成员类。
Attachmentch代码如下:
using System;
namespace PrototypeSample
{
[Serializable]
class Attachment
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
public void Download()
{
Console.WriteLine("下载附件,文件名为{0}。",name);
}
}
}
4、WeeklyLog类代码如下:
using System;
using System.IO;
using System.Collections;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
namespace PrototypeSample
{
[Serializable]
class WeeklyLog
{
private Attachment attachment;
private string name;
private string date;
private string content;
public Attachment Attachment
{
get { return attachment; }
set { attachment = value; }
}
public string Name
{
get { return name; }
set { name = value; }
}
public string Date
{
get { return date; }
set { date = value; }
}
public string Content
{
get { return content; }
set { content = value; }
}
/*
//使用MemberwiseClone()方法实现浅克隆
public WeeklyLog Clone()
{
return this.MemberwiseClone() as WeeklyLog;
}
*/
//使用序列化方式实现深克隆
public WeeklyLog Clone()
{
WeeklyLog clone = null;
//序列化
FileStream fs = new FileStream("Temp.dat", FileMode.Create);
BinaryFormatter formatter = new BinaryFormatter();
try
{
//对当前对象执行序列化操作到Temp.dat
formatter.Serialize(fs, this);
}
catch (SerializationException e)
{
Console.WriteLine("Failed to serialize. Reason: " + e.Message);
throw;
}
finally
{
fs.Close();
}
//反序列化
FileStream fs1 = new FileStream("Temp.dat", FileMode.Open);
BinaryFormatter formatter1 = new BinaryFormatter();
try
{
//从流中反序列化到对象
clone = (WeeklyLog)formatter1.Deserialize(fs1);
}
catch (SerializationException e)
{
Console.WriteLine("Failed to deserialize. Reason: " + e.Message);
throw;
}
finally
{
fs.Close();
}
return clone;
}
}
}
5、 客户端测试类Program:
using System;
namespace PrototypeSample
{
class Program
{
static void Main(string[] args)
{
/*
ConcretePrototypeB prototype, copy;
prototype = new ConcretePrototypeB();
//prototype.Attr = "Sunny";
copy = (ConcretePrototypeB)prototype.Clone();
//copy.Attr = "Tom";
Console.WriteLine(prototype == copy);
//Console.WriteLine(prototype.GetType() == copy.GetType());
Console.WriteLine(prototype.Member == copy.Member);
Console.Read();
*/
WeeklyLog log_previous, log_new;
log_previous = new WeeklyLog();
Attachment attachment = new Attachment();
log_previous.Attachment = attachment;
log_new = log_previous.Clone();
Console.WriteLine("周报是否相同?{0}",(log_previous == log_new)?"是":"否");
Console.WriteLine("附件是否相同?{0}",(log_previous.Attachment == log_new.Attachment)?"是":"否");
Console.Read();
}
}
}
6、 编译及运行程序,输出如下结果:
7、 深克隆解决方案:
1) 将周报类WeeklyLog和附件类Attachment标记为可序列化(Serializable)
[Serializable]
class WeeklyLog
{
private Attachment attachment;
……
}
[Serializable]
class Attachment
{
……
}
//使用序列化方式实现深克隆
public WeeklyLog Clone()
{
WeeklyLog clone = null;
FileStream fs = new FileStream("Temp.dat", FileMode.Create);
BinaryFormatter formatter = new BinaryFormatter();
try
{
formatter.Serialize(fs, this); //序列化
}
catch (SerializationException e)
{
Console.WriteLine("Failed to serialize. Reason: " + e.Message);
throw;
}
finally
{
fs.Close();
}
FileStream fs1 = new FileStream("Temp.dat", FileMode.Open);
BinaryFormatter formatter1 = new BinaryFormatter();
try
{
clone = (WeeklyLog)formatter1.Deserialize(fs1); //反序列化
}
catch (SerializationException e)
{
Console.WriteLine("Failed to deserialize. Reason: " + e.Message);
throw;
}
finally
{
fs1.Close();
}
return clone;
}