备忘录模式又叫做快照模式(Snapshot Pattern)或Token模式,是对象的行为模式。
备忘录对象是一个用来存储另外一个对象内部状态的快照的对象。备忘录模式的用意是在不破坏封装的条件下,将一个对象的状态捕捉(Capture)住,并外部化,存储起来,从而可以在将来合适的时候把这个对象还原到存储起来的状态。备忘录模式常常与命令模式和迭代子模式一同使用。
使用场景:
在做数据更新的时候都会备份一份某一个时刻临时的数据状态;以便于在特殊时期方便进行数据撤销,保证数据完整性;
备份两种方式:
一、浅表备份
浅表备份就是新备份出来的对象除了值类型不是相互引用,引用类型还是公用一个对象;看如下代码运行结果:
[Serializable]
public class Address
{
public string Privince { get; set; }
public string City { get; set; }
}
[Serializable]
public class Person
{
/// <summary>
/// 名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 年龄
/// </summary>
public int Age { get; set; }
public Person()
{
Console.WriteLine("当前执行时间:" + DateTime.Now);
}
static void Main(string[] arge)
{
var person = new Person()
{
Name = "jack",
Age = 20,
Address = new Address()
{
Privince = "中国江苏",
City = "苏州"
}
};
//动态的获取一个对象的运行状态--浅表复制
var personCopy = (Person)person.MemberwiseClone();
Console.WriteLine($"person对象的city原值是:{person.Address.City}");
Console.WriteLine($"personCopy对象的city原值是:{personCopy.Address.City}");
person.Address.City = "苏州吴江区";
Console.WriteLine($"person对象的city值是:{person.Address.City}");
Console.WriteLine($"personCopy对象的city值是:{personCopy.Address.City}");
Console.ReadLine();
}
}
运行结果:
二、深备份
通过深备份出来的对象,无论是值类型还是引用类型都是全新的;对原来对象的修改不会影响到新对象的字段。
代码如下:
IProtoType接口定义:
public interface IProtoType
{
object Colne(Person person);
}
对象地址:
[Serializable]
public class Address
{
public string Privince { get; set; }
public string City { get; set; }
}
person类:
[Serializable]
public class Person:IProtoType
{
/// <summary>
/// 名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 年龄
/// </summary>
public int Age { get; set; }
public Person()
{
Console.WriteLine("当前执行时间:" + DateTime.Now);
}
/// <summary>
/// 地址
/// </summary>
public Address Address { get; set; }
/// <summary>
/// 复制对象的方法
/// </summary>
/// <returns></returns>
public object Colne( Person person)
{
//return this.MemberwiseClone();
MemoryStream memoryStream = new MemoryStream();
BinaryFormatter binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize(memoryStream, person);
memoryStream.Seek(0, SeekOrigin.Begin);
var newPerson = (Person)binaryFormatter.Deserialize(memoryStream);
memoryStream.Close();
return newPerson;
}
static void Main(string[] arge)
{
var person = new Person()
{
Name = "jack",
Age = 20,
Address = new Address()
{
Privince = "中国江苏",
City = "苏州"
}
};
//动态的获取一个对象的运行状态--深复制
var personCopy = (Person)person.Colne(person);
Console.WriteLine($"person对象的city原值是:{person.Address.City}");
Console.WriteLine($"personCopy对象的city原值是:{personCopy.Address.City}");
Console.WriteLine("将person对象的city赋值成苏州吴江区");
person.Address.City = "苏州吴江区";
Console.WriteLine($"person对象的city值是:{person.Address.City}");
Console.WriteLine($"personCopy对象的city值是:{personCopy.Address.City}");
Console.ReadLine();
}
}
运行结果: