设计模式(备忘录模式)
参考:Learning hard
1.理解:备忘录模式就是对某个类的状态进行保存下来,等到需要恢复的时候,可以从备忘录中进行恢复。生活中这样的例子经常看到,如备忘电话通讯录,备份操作操作系统,备份数据库等。
2.模式中的角色如下:1.发起人角色:记录当前时刻的内部状态,负责创建和恢复备忘录数据。
2.备忘录角色:负责存储发起人对象的内部状态,在进行恢复时提供给发起人需要的状态。
3.管理者角色:负责保存备忘录对象
下面是一个实例,手机通讯录联系人备份与还原,可以备份不同的版本,并且还原
3.代码:
using ICSharpCode.SharpZipLib.Checksums;
using ICSharpCode.SharpZipLib.Zip;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
using System.Linq;
namespace ConsoleApplication1
{
//联系人
public class ContactPerson
{
public string Name { get;set;}
public string MobileName { get; set; }
}
//发起人
public class MobileOwner
{
//发起人需要保存的内部状态
public List<ContactPerson> ContactPersons { get; set; }
public MobileOwner(List<ContactPerson> persons)
{
ContactPersons = persons;
}
//创建备忘录,将当期要保存的联系人列表导入到备忘录中
// 这里也应该传递深拷贝,new List方式传递的是浅拷贝,
// 因为ContactPerson类中都是string类型,所以这里new list方式对ContactPerson对象执行了深拷贝
// 如果ContactPerson包括非string的引用类型就会有问题,所以这里也应该用序列化传递深拷贝
public ContactMemento CreateMemento()
{
return new ContactMemento(new List<ContactPerson>(this.ContactPersons));
}
//将备忘录的数据导入到联系人列表中
public void RestoreMemento(ContactMemento memento)
{
this.ContactPersons = memento.contactPersonBack;
}
//打印联系人
public void Show()
{
Console.WriteLine("联系人列表中有{0}个人,他们是:", this.ContactPersons.Count);
foreach (ContactPerson p in ContactPersons)
{
Console.WriteLine("姓名:{0} 号码:{1}", p.Name, p.MobileName);
}
}
}
//备忘录
public class ContactMemento
{
//保存发起人的内部状态
public List<ContactPerson> contactPersonBack;
public ContactMemento(List<ContactPerson> persons)
{
contactPersonBack = persons;
}
}
//管理角色
public class Caretaker
{
public Dictionary<string, ContactMemento> contactMementoDic = new Dictionary<string, ContactMemento>();
public ContactMemento ContacM { get; set; }
}
public class Program
{
static void Main()
{
List<ContactPerson> persons = new List<ContactPerson> { new ContactPerson() { Name = "张三", MobileName = "12423425" }, new ContactPerson() { Name = "李四", MobileName = "7567675567" }, new ContactPerson() { Name = "王五", MobileName = "45646456" } };
MobileOwner mobileOwner = new MobileOwner(persons);
mobileOwner.Show();
//创建备忘录并保存备忘录对象
Console.WriteLine("-------第一次备份-------");
Caretaker caretaker = new Caretaker();
caretaker.contactMementoDic.Add(DateTime.Now.ToString(), mobileOwner.CreateMemento());
//发起人更改联系人列表
Console.WriteLine("-------移除最后一个联系人--------");
mobileOwner.ContactPersons.RemoveAt(2);
mobileOwner.Show();
//再次备份之前间隔3秒
Thread.Sleep(3000);
Console.WriteLine("--------第二次备份--------");
caretaker.contactMementoDic.Add(DateTime.Now.ToString(), mobileOwner.CreateMemento());
//恢复到原始状态
Console.WriteLine("-------恢复联系人列表,请从一下列表选择恢复的日期---------");
foreach (string k in caretaker.contactMementoDic.Keys)
{
Console.WriteLine(k);
}
while (true)
{
Console.WriteLine("请输入数字,按窗口的关闭键退出");
int index = -1;
try
{
index = Int32.Parse(Console.ReadLine());
}
catch
{
Console.WriteLine("输入格式错误");
continue;
}
ContactMemento contactMemento = null;
if (index < caretaker.contactMementoDic.Keys.Count &&caretaker.contactMementoDic.TryGetValue(caretaker.contactMementoDic.Keys.ElementAt(index),out contactMemento ))
{
mobileOwner.RestoreMemento(contactMemento);
mobileOwner.Show();
}
else
{
Console.WriteLine("输入的索引大于集合长度!");
}
}
}
}
}