`

回到过去的备忘录模式(Nemento Pattern)

阅读更多

今天学习一个比较少用的备份模式-----备忘录模式。通过名字应该都可以知道其作用了,就是对象或对象属性作备份,方便随便取回。拿打怪来说,开始我有100血,打着打着,剩20了,我想重玩,重新回到100血的状态。用备忘录实现此情形的类图如下:



没错,一个简单的功能备忘录标准要用三个类实现。可能你会说为什么要个备忘录管理类,没必要啊,没有管理类功能照样可以实现,但是这样客户端需要关心备忘录,这对迪米特法则是一种亵渎。对高层模块来说,它最希望要做的就是创建一个备份点,然后在需要的时候再恢复到这个备份点就成了,它不用关心到底有没有备忘录这个类。因此才有了备忘录管理类的存在。下面看实现代码:

<?php
class Gamer {
	private $blood = 0;
	public function getBlood() {
		return $this->blood;
	}
	public function setBlood( $blood ) {
		$this->blood = $blood;
	}
	public function createMemento() {
		return new Memento( $this->blood );
	}
	public function restoreMemento( Memento $memento ) {
		$this->setBlood( $memento->getBlood() );
	}
}


class Memento {
	private $blood = 0;
	public function __construct( $blood ) {
		$this->blood = $blood;
	}
	public function getBlood() {
		return $this->blood;
	}
	public function setBlood( $blood ) {
		$this->blood = $blood;
	}
}

class Caretasker {
	private $memento;
	public function getMemento() {
		return $this->memento;
	}
	public function setMemento( Memento $memento ) {
		$this->memento = $memento;
	}
}

$caretasker = new Caretasker();
$gamer = new Gamer();
$gamer->setBlood(100);
echo "初始血量:100\n";
$caretasker->setMemento($gamer->createMemento());
$gamer->setBlood(20);
echo "打怪后血量:20\n";
$gamer->restoreMemento($caretasker->getMemento());
echo "重玩恢复血量:".$gamer->getBlood();
?>
运行结果:
初始血量:100
打怪后血量:20
重玩恢复血量:100[Finished in 0.3s]

 

 

备忘录模式的定义

备忘录模式提供了一种弥补真实世界缺陷的方法,让“后悔药”在程序的世界中真实可行。其定义为:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之个保存这个状态。这样以后就可将对象恢复到原先保存的状态。其主要由三个角色构成:

1、Originator发起人角色

记录当前时刻的内部状态,负责定义哪些属于备份范围的状态,负责创建和恢复备忘录数据。

2、Memento备忘录角色

负责存储Originator发起人对象的内部状态,在需要的时候提供发起人需要的内部状态。

3、Caretaker备忘录管理员角色

对备忘录进行管理、保存和提供备忘录

 

 

 

备忘录模式的应用

由于备忘录模式有太多的变形和处理方式,每种方式都有它自己的优点和缺点,标准和备忘模式很难在项目中遇到,基本上都有一些变换处理方式。因此,在使用备忘录模式时主要了解如何应用以需要注意哪些事项就成了

 

 

 

备忘录模式的使用场景

1、需要保存和恢复数据的相关状态场景

2、提供一个可回滚操作

3、需要监控的一个副本场景中。例如要监控一个对象的属性,但是监控又不应该作为系统的主业务来调用,它只是边缘应用,即使出现监控不准,错误报警也影响不大,因此一般的做法是备份一个主线程的对象,然后由分析程序来分析。

4、数据库连接的事务管理就是用的备忘录模式。

 

 

备忘录模式的注意事项

1、备忘录的生命期

备忘录创建出来就要在“最近”的代码中使用,要主动管理它的生命周期,建立就要使用,不使用就要立刻删除其引用,等待垃圾回收器对它的回收处理

2、备忘录的性能

不要在频繁建立备份的场景中使用备忘录模式(比如一个for循环中),原因有二:一是控制不了备忘录建立的对象数量,二是大对象的建立是要消耗资源的,系统的性能需要考虑。

 

 

 

备忘录模式的扩展

1、clone方式的备忘录

为保存一个状态写三个类太烦?还记得以前学过的原型模式吗?现在使用原型模式来实现:

<?php
class Gamer {
	private $blood = 0;
	private $backup;
	public function getBlood() {
		return $this->blood;
	}
	public function setBlood( $blood ) {
		$this->blood = $blood;
	}
	public function createMemento() {
		$this->backup = clone $this;
	}
	public function restoreMemento() {
		$this->setBlood( $this->backup->getBlood() );
	}
}


$gamer = new Gamer();
$gamer->setBlood(100);
echo "初始血量:100\n";
$gamer->createMemento();
$gamer->setBlood(20);
echo "打怪后血量:20\n";
$gamer->restoreMemento();
echo "重玩恢复血量:".$gamer->getBlood();
?>
运行结果:
初始血量:100
打怪后血量:20
重玩恢复血量:100[Finished in 0.3s]

 天啊,太简单了是不。但这还是备忘录模式吗?它定义是“在该对象之外保存这个状态”,而现在却把这个状态保存在发起人内部。是的,设计模式定义的诞生过早,它没有想到之后的程序是这么有活力,有远见,而且在面对对象的设计中,即使把一个类封装在另一个类中也是可以做到的,何况一个小小的对象复制,这是它的设计模式完全没有预见到的。注意的是,使用clone方式的备忘录模式,可以使用在比较简单的场景或者比较单一场景中,尽量不要与其他的对象产生严重的耦合关系。

 

2、多状态的备忘录模式

这个就是备份多个属性,在之前的例子除了保存“血量”外,比如再保存个“气量”。

3、多备份的备忘录

4、封装得更好一点

在系统管理中,一个备份的数据是完全、绝对不能修改的,它保证数据的洁净,避免数据污染而使备份失去意义。

 

 

备忘录模式是设计上的“月光宝盒”,可以让我们回到需要的年代,是程序数据的“后悔药”,吃了它就可以返回上一个状态,是设计人员的定义丸,确保即使在最坏的情况下也能获取最近的对象状态。因此,在设计的时候就不要使用数据库的临时表作为缓存备份数据了,虽然是一个简单的方法,但是它加大了数据库操作的频繁度,把压力下放到数据库了,最好的解决方法就是使用备忘录模式

  • 大小: 7.7 KB
1
0
分享到:
评论

相关推荐

    设计模式之备忘录模式(Memento Pattern)

    备忘录模式(Memento Pattern)是软件设计模式中的一种行为模式,它的主要目的是在不破坏对象封装性的前提下,允许对象在特定时刻保存其内部状态,并能够在之后恢复到保存时的状态。这种模式广泛应用于撤销/重做功能...

    备忘录模式.rar备忘录模式.rarjava设计模式

    备忘录模式是一种行为设计模式,它允许在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将对象恢复到原先保存的状态。这种模式常用于需要记录用户操作历史或者游戏进度...

    设计模式之备忘录模式

    备忘录模式(Memento Pattern)是软件设计模式中的一种,属于行为模式。它提供了一种方式来恢复对象到之前的状态,即“撤销”操作。备忘录模式的核心思想是保存对象的内部状态,以便在需要时能恢复到这个状态,而...

    设计模式-备忘录模式(讲解及其实现代码)

    备忘录模式是一种在软件工程中广泛使用的面向对象设计模式,它主要用来安全地保存对象的状态,以便在需要时能够恢复到先前的状态。备忘录模式的核心思想是封装对象的状态,将其保存到一个独立的对象(备忘录)中,而...

    设计模式之备忘录模式,内含可运行代码及详细解释

    备忘录模式是一种常用的设计模式,它在软件工程中扮演着重要的角色,特别是在需要保护对象内部状态不被外部篡改的场景下。备忘录模式的核心思想是提供一种方法来捕获一个对象的内部状态,并在该对象之外保存这个状态...

    java设计模式-备忘录模式源代码

    备忘录模式是一种在软件工程中广泛使用的面向对象设计模式,它主要用来安全地保存对象的状态,以便在需要时能够恢复到先前的状态。这个模式的名字来源于我们日常生活中使用的备忘录,它记录了一些重要的信息,当需要...

    C#面向对象设计模式纵横谈(21):(行为型模式) Memento 备忘录模式

    备忘录模式(Memento Pattern)是一种行为设计模式,它允许在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将对象恢复到先前的状态。这种模式在需要撤销/重做功能、...

    设计模式_备忘录模式.zip

    备忘录模式是一种在软件工程中广泛使用的结构型设计模式,其主要目的是为了在不破坏封装性的前提下,能够安全地保存对象的状态,并在需要时恢复到先前保存的状态。这种模式通常用于那些需要记录和回滚操作的重要场景...

    备忘录模式Demo

    备忘录模式是一种设计模式,它在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将对象恢复到原先保存的状态。这种模式常用于需要记录用户操作或者游戏进度等场景,允许...

    C#备忘录模式 代码例子

    备忘录模式是一种设计模式,它在不破坏封装性的前提下,保存对象的内部状态,以便在需要的时候恢复。在C#中,备忘录模式常用于实现撤销/重做功能,或者在需要记录和恢复对象状态的情况下。下面将详细解释备忘录模式...

    备忘录模式实现及案例

    备忘录模式是一种设计模式,属于行为模式类型,它的主要作用是保存对象的状态,以便在需要的时候能够恢复到之前的状态。这种模式的核心在于提供一种方式,可以在不破坏封装的前提下,捕获并存储一个对象的内部状态,...

    设计模式之备忘录模式的Java版本实现

    备忘录模式是一种在软件设计中广泛使用的结构型设计模式,它的主要目的是为了保存对象的状态,以便在需要的时候能够恢复到之前的状态。备忘录模式的核心思想是通过创建一个备忘录对象来存储原对象的状态,这个备忘录...

    备忘录模式 C++ 实现

    备忘录模式是一种行为设计模式,它允许在不破坏封装性的前提下,捕获和恢复一个对象的内部状态。在C++中实现备忘录模式,可以有效地帮助开发者在程序运行过程中保存对象的状态,以便在需要时恢复到之前的状态,这...

    设计模式 - 备忘录模式(C++实例)

    备忘录模式是一种在不破坏封装性的前提下,捕获一个对象的状态,并允许在未来的某个时刻恢复这个状态的设计模式。这种模式在很多场景下都非常有用,例如在游戏中保存进度、在编辑器中撤销/重做操作等。备忘录模式的...

    设计模式-备忘录

    备忘录模式是一种常用的设计模式,它在软件工程中用于保存对象的状态,以便在需要时恢复到之前的状态。这种模式的主要目标是实现数据的安全存储,同时保持对象的封装性,避免对外部对象直接访问其内部状态。在iOS...

    Java设计模式-备忘录

    **Java设计模式——备忘录模式详解** 备忘录模式是一种行为设计模式,它允许对象在不破坏封装性的前提下捕获并存储其内部状态,以便稍后恢复到该状态。这种模式常用于在游戏中保存进度、撤销/重做操作、以及在复杂...

    备忘录模式笔记1

    备忘录模式笔记 备忘录模式(Memento)是一种非常有用的设计模式,它主要用于保存一个对象的某个状态,以便在适当的时候恢复对象。下面我们将对备忘录模式进行详细的解释和分析。 备忘录模式的定义 备忘录模式是...

    iOS 设计模式 备忘录模式

    在iOS开发中,设计模式是一种解决常见编程问题的模板,可以提高代码的可读性、可维护性和可重用性。...在MementoPattern-master项目中,开发者可以深入学习和理解备忘录模式的具体实现和应用场景。

    备忘录模式代码示例

    备忘录模式是一种设计模式,它允许对象在不破坏封装性的前提下,捕获和存储其内部状态,以便在需要时能恢复到该状态。这种模式在需要保存和恢复对象状态,而又不想对外部世界暴露其内部实现细节时非常有用。备忘录...

    设计模式之备忘录模式(Memento)

    备忘录模式(Memento Pattern)是设计模式中的一种行为模式,主要目的是在不违反封装原则的情况下,保存一个对象的内部状态,以便在需要时能够恢复到先前的状态。这种模式通常用于实现撤销/重做功能或者在游戏中保存...

Global site tag (gtag.js) - Google Analytics