[设计模式学以致用]备忘录模式
2016-04-25 18:26
211 查看
[格物致知|深入浅出|学以致用]
不破坏封闭
对象的内部状态
在该对象之外
这三个要点是从备忘录模式的定义中提炼出来的,但如果要更容易的理解,应该把它们的顺序颠倒一下。如下:
在该对象之外
对象的内部状态
不破坏封闭
下面我们来依次分析一下这几个要点。
这个要点其实是其他设计模式和原则的要求。
但是如果想要保存某一个状态下的完整对象,私有变量的值也是需要保存下来的。
这个要点是该设计模式的前提。
问题:在一个对象之外对该对象的内部私有变量并进行保存。
一般遇到这样的问题,常用的处理方法有两种:
第一,违背要点一,改由该对象自己进行数据保存,并新增一个公用方法给外部调用;
第二,违背要点二,将类的私有变量改为公有变量,让外部的对象直接访问,并进行保存。
看到这里有人不禁要问,上面这两个方法已经违背了这个设计模式定义的前提,怎么叫解决方法呢?作者你难道在讲笑话?
其实不然,现实的编程工作中有这无数的迁就和妥协,而上面这两个方法就是现实的写照~(此处应该有憨笑emoji)
或许Gof为了避免大家使用这两个取巧的办法,所以加了第三个要点作为强调——“不破坏封闭”。
这样就要求我们直面这个貌似悖论的问题:如何在对象外保存对象的私有变量?
对象外部需要保存对象内部变量,两者无法直接沟通,那么必然需要一个中间产物来作为中介。即对象将内部变量放在中间产物中,然后交由对象外部,对象外部将该中间产物进行保存。
而数据恢复时,对象外部先读取到中间产物,然后将中间产物交给对象,对象自己恢复中间产物中的数据。
这样一来就完全满足了模式定义中的三个要点,没有破坏封闭,在对象外部保存对象的内部变量。
而这里所谓的中间产物,便是该模式的名称——备忘录。
备忘录模式中的三个角色分别为发起人Originator、备忘录Memento、管理者Caretaker。这些角色分类充分体现了设计模式的单一职责原则,发起人负责业务功能,向业务系统提供数据;备忘录只负责为保存功能提供组织好的数据;管理者负责具体的保存功能。
备忘录为了满足信息的封闭,即部分数据向发起人开放,而不向管理者开放,正常来说需要两个接口,这便是常说的宽接口和窄接口。宽接口提供完整的数据访问,以便发起人能够据此恢复数据。而管理者只需要保存备忘录本身,所以只需要一个最小的窄接口即可。
不过设计模式的意义在于举一反三,所以其可以应用的外延大多超过了其定义。
即便现在的应用场景不是保存对象的内部变量,而是保存对象的公开变量,从迪米特法则来看,也不应该由管理者直接进行保存,而应该由发起人自己保存。但发起人自己保存,又违反了单一职责原则。若是由管理者直接将发起人保存,那样当需要保存发起人的部分变量时,这样的功能又有些冗余。如此一来,便又回到了备忘录模式上——2.需要保存对象的部分变量时。
1. 定义
所谓备忘录模式,就是在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可将该对象恢复到原先保存的状态。2. 格物
对于备忘录模式,有几个点需要注意:不破坏封闭
对象的内部状态
在该对象之外
这三个要点是从备忘录模式的定义中提炼出来的,但如果要更容易的理解,应该把它们的顺序颠倒一下。如下:
在该对象之外
对象的内部状态
不破坏封闭
下面我们来依次分析一下这几个要点。
2.1. 在该对象之外
这个点其实是要求将数据模型类和数据的保存操作解耦合,不由该对象自己进行数据的持久化,以免具体的保存逻辑出现变动时而改动该类的实现。这个要点其实是其他设计模式和原则的要求。
2.2. 对象的内部状态
众所周知,在面向对象概念的类定义中,存在私有变量和公有变量之分,而备忘录模式定义中所强调的“对象的内部状态”应该就是指类似的私有变量。对象的内部状态只是跟对象自己的行为有关,所以并没有开放给其他类的实例访问。但是如果想要保存某一个状态下的完整对象,私有变量的值也是需要保存下来的。
这个要点是该设计模式的前提。
2.3. 不破坏封闭
这个要点是该设计模式的精髓所在,有了前两个的铺垫,那这个要点就很容易理解了。问题:在一个对象之外对该对象的内部私有变量并进行保存。
一般遇到这样的问题,常用的处理方法有两种:
第一,违背要点一,改由该对象自己进行数据保存,并新增一个公用方法给外部调用;
第二,违背要点二,将类的私有变量改为公有变量,让外部的对象直接访问,并进行保存。
看到这里有人不禁要问,上面这两个方法已经违背了这个设计模式定义的前提,怎么叫解决方法呢?作者你难道在讲笑话?
其实不然,现实的编程工作中有这无数的迁就和妥协,而上面这两个方法就是现实的写照~(此处应该有憨笑emoji)
或许Gof为了避免大家使用这两个取巧的办法,所以加了第三个要点作为强调——“不破坏封闭”。
这样就要求我们直面这个貌似悖论的问题:如何在对象外保存对象的私有变量?
3.致知
有了对前面三个要点的分析,那么现状就很明了了。对象外部需要保存对象内部变量,两者无法直接沟通,那么必然需要一个中间产物来作为中介。即对象将内部变量放在中间产物中,然后交由对象外部,对象外部将该中间产物进行保存。
而数据恢复时,对象外部先读取到中间产物,然后将中间产物交给对象,对象自己恢复中间产物中的数据。
这样一来就完全满足了模式定义中的三个要点,没有破坏封闭,在对象外部保存对象的内部变量。
而这里所谓的中间产物,便是该模式的名称——备忘录。
备忘录模式中的三个角色分别为发起人Originator、备忘录Memento、管理者Caretaker。这些角色分类充分体现了设计模式的单一职责原则,发起人负责业务功能,向业务系统提供数据;备忘录只负责为保存功能提供组织好的数据;管理者负责具体的保存功能。
备忘录为了满足信息的封闭,即部分数据向发起人开放,而不向管理者开放,正常来说需要两个接口,这便是常说的宽接口和窄接口。宽接口提供完整的数据访问,以便发起人能够据此恢复数据。而管理者只需要保存备忘录本身,所以只需要一个最小的窄接口即可。
4.致用
根据备忘录模式的定义,我们很容易便可以找到该模式适用的第一个场景——1.需要在对象外保存对象的内部变量时。不过设计模式的意义在于举一反三,所以其可以应用的外延大多超过了其定义。
即便现在的应用场景不是保存对象的内部变量,而是保存对象的公开变量,从迪米特法则来看,也不应该由管理者直接进行保存,而应该由发起人自己保存。但发起人自己保存,又违反了单一职责原则。若是由管理者直接将发起人保存,那样当需要保存发起人的部分变量时,这样的功能又有些冗余。如此一来,便又回到了备忘录模式上——2.需要保存对象的部分变量时。
相关文章推荐
- PropertyChangeListener简单理解
- 什么是设计模式
- 设计模式之创建型模式 - 特别的变量问题
- 七、设计模式——装饰模式
- 设计模式总结
- 设计模式之创建型模式
- 浅谈设计模式的学习
- Ruby设计模式编程之适配器模式实战攻略
- 实例讲解Ruby使用设计模式中的装饰器模式的方法
- 设计模式中的模板方法模式在Ruby中的应用实例两则
- Ruby设计模式编程中对外观模式的应用实例分析
- 实例解析Ruby设计模式编程中Strategy策略模式的使用
- Ruby中使用设计模式中的简单工厂模式和工厂方法模式
- Ruby使用设计模式中的代理模式与装饰模式的代码实例
- 详解组合模式的结构及其在Ruby设计模式编程中的运用
- C#编程中使用设计模式中的原型模式的实例讲解
- 使用设计模式中的工厂方法模式进行C#编程的示例讲解
- 实例解析C#设计模式编程中简单工厂模式的使用
- 详解C#设计模式编程中生成器模式的使用
- 深入解析C#设计模式编程中对建造者模式的运用