设计模式(22)——备忘录模式

备忘录模式(Memento Pattern)保存一个对象的某个状态,以便在适当的时候恢复对象。备忘录模式属于行为型模式。

角色
发起人角色:记录当前时刻的内部状态,负责创建和恢复备忘录数据。
备忘录角色:负责存储发起人对象的内部状态,在进行恢复时提供给发起人需要的状态。
管理者角色:负责保存备忘录对象。
联系人

public class ContactPerson
{
    public string Name { get; set; }
    public string MobileNum { get; set; }
}

备忘录

public class ContactMemento
{
    public List<ContactPerson> ContactPersonBack { get; set; }
    public ContactMemento(List<ContactPerson> persons)
    {
        ContactPersonBack = persons;
    }
}

发起人

public class MobileOwner
{
    public List<ContactPerson> ContactPersons { get; set; }
    public MobileOwner(List<ContactPerson> persons)
    {
        ContactPersons = persons;
    }

    // 创建备忘录,将当期要保存的联系人列表导入到备忘录中 
    public ContactMemento CreateMemento()
    {
        // 这里也应该传递深拷贝,new List方式传递的是浅拷贝,
        // 因为ContactPerson类中都是string类型,所以这里new list方式对ContactPerson对象执行了深拷贝
        // 如果ContactPerson包括非string的引用类型就会有问题,所以这里也应该用序列化传递深拷贝
        return new ContactMemento(new List<ContactPerson>(this.ContactPersons));
    }

    // 将备忘录中的数据备份导入到联系人列表中
    public void RestoreMemento(ContactMemento memento)
    {
        if (memento != null)
        {
            // 下面这种方式是错误的,因为这样传递的是引用,
            // 则删除一次可以恢复,但恢复之后再删除的话就恢复不了.
            // 所以应该传递contactPersonBack的深拷贝,深拷贝可以使用序列化来完成
            this.ContactPersons = memento.ContactPersonBack;
        }
    }
    public void Show()
    {
        Console.WriteLine("联系人列表中有{0}个人,他们是:", ContactPersons.Count);
        foreach (ContactPerson p in ContactPersons)
        {
            Console.WriteLine("姓名: {0} 号码为: {1}", p.Name, p.MobileNum);
        }
    }
}

管理员

public class Manager
{
    // 使用多个备忘录来存储多个备份点
    public ContactMemento ContactMemento { get; set; }
}

调用

class Program
{
    static void Main(string[] args)
    {
        List<ContactPerson> persons = new List<ContactPerson>()
        {
            new ContactPerson() { Name = "刘德华", MobileNum = "123456"},
            new ContactPerson() { Name = "吴彦祖", MobileNum = "111"},
            new ContactPerson() { Name = "我", MobileNum = "666"}
        };

        MobileOwner mobileOwner = new MobileOwner(persons);
        mobileOwner.Show();

        // 创建备忘录并保存备忘录对象
        Manager manager = new Manager();
        manager.ContactMemento = mobileOwner.CreateMemento();

        // 更改发起人联系人列表
        Console.WriteLine("----移除最后一个联系人--------");
        mobileOwner.ContactPersons.RemoveAt(2);
        mobileOwner.Show();

        // 恢复到原始状态
        Console.WriteLine("----恢复联系人列表--------");
        mobileOwner.RestoreMemento(manager.ContactMemento);
        mobileOwner.Show();
        Console.Read();
    }
}

结果

联系人列表中有3个人,他们是:
姓名: 刘德华 号码为: 123456
姓名: 吴彦祖 号码为: 111
姓名: 我 号码为: 666
----移除最后一个联系人--------
联系人列表中有2个人,他们是:
姓名: 刘德华 号码为: 123456
姓名: 吴彦祖 号码为: 111
----恢复联系人列表--------
联系人列表中有3个人,他们是:
姓名: 刘德华 号码为: 123456
姓名: 吴彦祖 号码为: 111
姓名: 我 号码为: 666

类图

在这里插入图片描述

优点与缺点

备忘录模式的优点:

  • 如果某个操作错误地破坏了数据的完整性,此时可以使用备忘录模式将数据恢复成原来正确的数据。
  • 备份的状态数据保存在发起人角色之外,这样发起人就不需要对各个备份的状态进行管理。而是由备忘录角色进行管理,而备忘录角色又是由管理者角色管理,符合单一职责原则。

备忘录模式的缺点:

  • 在实际的系统中,可能需要维护多个备份,需要额外的资源,这样对资源的消耗比较严重。

本文主要借鉴了《Gof设计模式》与C#设计模式(23)——备忘录模式(Memento Pattern)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值