`
亚当爱上java
  • 浏览: 707192 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Android设计模式系列(5)--SDK源码之备忘录模式

 
阅读更多

定义(源于GoF《设计模式》):在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。

 

涉及角色

 

1.Originator(发起人):负责创建一个备忘录Memento,用以记录当前时刻自身的内部状态,并可使用备忘录恢复内部状态。Originator可以根据需要决定Memento存储自己的哪些内部状态。

 

2.Memento(备忘录):负责存储Originator对象的内部状态,并可以防止Originator以外 的其他对象访问备忘录。备忘录有两个接口:Caretaker只能看到备忘录的窄接口,他只能将备忘录传递给其他对象。Originator却可看到备忘 录的宽接口,允许它访问返回到先前状态所需要的所有数据。

 

3.Caretaker(管理者):负责保存好备忘录Memento,不能对Memento的内容进行访问或者操作。

备忘录模式,在工作代码中,要么不用,要么经常用到。
以保存游戏进度为例,在游戏角色大战Boss前将该角色的状态存储,与Boss作战后角色的各项能力会下降,如果没有通关,则可利用备忘录进行恢复到战前状态。

 

游戏角色类

package com.zyh.designpattern.memento;

public class PlayRole {
	private int vitality;
	private int aggressivity;
	private int defencivity;

	public PlayRole(int vitality, int aggressivity, int defencivity) {
		super();
		this.vitality = vitality;
		this.aggressivity = aggressivity;
		this.defencivity = defencivity;
	}

	public PlayRole() {
	}

	public int getVitality() {
		return vitality;
	}

	public void setVitality(int vitality) {
		this.vitality = vitality;
	}

	public int getAggressivity() {
		return aggressivity;
	}

	public void setAggressivity(int aggressivity) {
		this.aggressivity = aggressivity;
	}

	public int getDefencivity() {
		return defencivity;
	}

	public void setDefencivity(int defencivity) {
		this.defencivity = defencivity;
	}

	public RoleMemento createMemento() {
		RoleMemento memento = new RoleMemento();
		memento.setAggressivity(aggressivity);
		memento.setDefencivity(defencivity);
		memento.setVitality(vitality);
		return memento;
	}

	public void setMemento(RoleMemento memento) {
		this.aggressivity = memento.getAggressivity();
		this.defencivity = memento.getDefencivity();
		this.vitality = memento.getVitality();
	}

	public void showState() {
		System.out.println("攻击力:" + this.aggressivity + "|防御力:"
				+ this.defencivity + "|生命力:" + this.vitality);
	}
}
 

 

 

备忘录类:

package com.zyh.designpattern.memento;

public class RoleMemento {
	private int vitality;
	private int aggressivity;
	private int defencivity;

	public int getVitality() {
		return vitality;
	}

	public void setVitality(int vitality) {
		this.vitality = vitality;
	}

	public int getAggressivity() {
		return aggressivity;
	}

	public void setAggressivity(int aggressivity) {
		this.aggressivity = aggressivity;
	}

	public int getDefencivity() {
		return defencivity;
	}

	public void setDefencivity(int defencivity) {
		this.defencivity = defencivity;
	}
}
 

 

 

管理者类

package com.zyh.designpattern.memento;

public class Caretaker {
	RoleMemento memento;

	public RoleMemento getMemento() {
		return memento;
	}

	public void setMemento(RoleMemento memento) {
		this.memento = memento;
	}
}
 

 

 

客户端:

package com.zyh.designpattern.memento;

public class Client {
	public static void main(String[] args) {
		// 测试程序
		// 新建角色
		PlayRole role = new PlayRole(100, 100, 100);
		// 新建管理者
		Caretaker taker = new Caretaker();
		// 角色初始状态
		System.out.println("游戏刚开始,角色各属性:");
		role.showState();
		// 利用备忘录模式保存当前状态
		System.out.println("\n【保存游戏状态!】\n");
		taker.setMemento(role.createMemento());
		role.setAggressivity(20);
		role.setDefencivity(30);
		role.setVitality(0);
		// 大战过后,角色能力值下降
		System.out.println("与Boss对战后,角色各项能力已大大下降:");
		role.showState();
		// 恢复保存的角色状态
		role.setMemento(taker.getMemento());
		System.out.println("\n【恢复保存的角色状态!】");
		System.out.println("\n恢复后角色的当前状态:");
		role.showState();
	}
}
 

 
本文今天就Canvas的一个save(),restore()操作分析一下,但是有一点,看完本文,如果不懂备忘录模式的,应该还是不懂,但是canvas是android的一场大戏,说一说它的特色,对深入学习android绝对有帮助。
学习备忘录模式,通过保存状态,恢复状态的内部实现,对了解一些莫名其妙的看上去无用其实很重要的操作有拨开云雾见青天的作用。

 

1.意图
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可以将该对象恢复到先前保存的状态。
热门词汇:标记 状态 备忘录 原发器

2.结构和代码

组 织者,把原发器的状态State(全部或者部分状态,一般是变量的值),通过CreateMemento()方法保存起来,继续运行后,等待合适的时机, 在通过SetMemento()方法可以再次恢复到之前的状态。在这个过程中,我们并没有对这些状态做任何的访问和设置,实际上这些状态都是私有的,对外 是禁止访问的,我们只是通过Memento对象的两个最简单的方法就达到了这个效果。Memento经常写成Originator的内部类。
在Android中,Canvas有两个方法 save()和restore()方法再做图形变换的时候使用的非常多,因为涉及到跨语言的问题,我不好就认定这个用的是备忘录模式,但是它的这种思想绝对是备忘录的思想。


我们来读一读它源代码的注释吧,首先看save()保存状态:

public class Canvas {
    /**
     * Saves the current matrix and clip onto a private stack. Subsequent
     * calls to translate,scale,rotate,skew,concat or clip Rect,clipPath
     * will all operate as usual, but when the balancing call to restore()
     * is made, those calls will be forgotten, and the settings that existed
     * before the save() will be reinstated.
     */
    /**
     *保存当前的矩阵和剪裁到一个私有的堆栈,其实矩阵和剪裁就是当前Canvas的状态State
     */
    public native int save();
}
 

  再看恢复状态restore():

public class Canvas {
    /**
     * This call balances a previous call to save(), and is used to remove all
     * modifications to the matrix/clip state since the last save call. It is
     * an error to call restore() more times than save() was called.
     */
    /**
     * 移除自上次保存操作后所做的修改,恢复到之前的状态,因为是堆栈实现,所以pull操作不能不等于push操作,save()和restore()应该成对使用,否则恢复的状态就很有可能是错误的
     */
    public native void restore();
}
 

  从上面的两个方法中,它们实现了自我状态的恢复,实际上我们只是执行了两个没有接触任何内部信息的方法,实际上这两个方法就是在操作我们看不到的这些内部状态信息。

3.效果
(1).保持封装边界,把很复杂的原发器的内部信息对外部其他对象隐藏起来。
(2).简化的原发器,把状态操作无形中转化到客户手里,简化了原发器的某些实现。
(3).也要注意注意备忘录的管理代价。

 

备忘录模式的优点和缺点
一、备忘录模式的优点

 

1、有时一些发起人对象的内部信息必须保存在发起人对象以外的地方,但是必须要由发起人对象自己读取,这时,

 

使用备忘录模式可以把复杂的发起人内部信息对其他的对象屏蔽起来,从而可以恰当地保持封装的边界。

 

2、本模式简化了发起人类。发起人不再需要管理和保存其内部状态的一个个版本,客户端可以自行管理他们所需

 

要的这些状态的版本。

 

3、当发起人角色的状态改变的时候,有可能这个状态无效,这时候就可以使用暂时存储起来的备忘录将状态复原。

 

二、备忘录模式的缺点:

 

1、如果发起人角色的状态需要完整地存储到备忘录对象中,那么在资源消耗上面备忘录对象会很昂贵。

 

2、当负责人角色将一个备忘录 存储起来的时候,负责人可能并不知道这个状态会占用多大的存储空间,从而无法提醒用户一个操作是否很昂贵。

 

3、当发起人角色的状态改变的时候,有可能这个协议无效。如果状态改变的成功率不高的话,不如采取“假如”协议模式。    
分享到:
评论

相关推荐

    opencv-4.5.4-android-sdk .zip

    opencv-4.5.4-android-sdk .zip

    opencv-3.4.4-android-sdk/sdk/其他文件.zip

    opencv-3.4.4-android-sdk/sdk/build.gradle opencv-3.4.4-android-sdk/sdk/etc opencv-3.4.4-android-sdk/sdk/java

    android-sdk-4.2.2 android-sdk-4.2.2-platforms

    标题中的"android-sdk-4.2.2 android-sdk-4.2.2-platforms"指的是Android SDK的一个特定版本,即Android 4.2.2(API级别17),该版本的SDK平台组件。这个版本是Android操作系统的 Jelly Bean 版本的一部分,发布于...

    aip-ocr-android-sdk-1.4.4.zip

    标题 "aip-ocr-android-sdk-1.4.4.zip" 暗示这是一个用于Android平台的OCR(光学字符识别)软件开发工具包,由百度公司提供,版本为1.4.4。这个SDK允许开发者集成到自己的应用程序中,实现图片中的文字自动识别功能...

    opencv-4.1.0-android-sdk

    本SDK是OpenCV的Android版本,版本号为4.1.0,适用于Android平台上的图像处理和计算机视觉应用开发。 在Android平台上使用OpenCV,开发者可以利用其强大的图像处理功能,如图像滤波、特征检测、图像变换、物体识别...

    android-19-sdk源码.zip

    Android Framework Source Code , sdk19的源码,附关联方法: 打开Eclipse,随便新建一个Android项目,在此项目目录下面有个Android 4.4,点击展开遍出现了android.jar。右键此包---->Properties,在弹出的窗口中,...

    android-sdk-r24.4.1-windows Android SDK Manager

    sdkmanager是一个命令行工具,您可以用它来查看、安装、更新和卸载 Android SDK 的软件包。如果使用 Android Studio,则无需使用此工具,而可以从 IDE 管理 SDK 软件包。

    taobao-sdk-java-auto源码

    taobao-sdk-java-auto源码, taobao-sdk-java-auto源码, taobao-sdk-java-auto源码, taobao-sdk-java-auto源码

    opencv-4.6.0-android-sdk.zip

    5. **构建系统**:OpenCV Android SDK可能包含了用于构建和配置项目的文件,如CMakeLists.txt或Android.mk,这使得开发者可以将OpenCV库添加到他们的Android Studio项目中。 6. **预训练模型**:有时,OpenCV会附带...

    android-4.1SDK android-sdk_r20-windows.zip

    android 4.1 最新SDK Windows版: http://s1.eoeandroid.com/sdk/4.1/android-sdk_r20-windows.zip(推荐) http://s1.eoeandroid.com/sdk/4.1/installer_r20-windows.exe Mac版: ...

    android-sdk-windows android-sdk-windows

    android-sdk-windowsandroid-sdk-windowsandroid-sdk-windowsandroid-sdk-windowsandroid-sdk-windowsandroid-sdk-windowsandroid-sdk-windows

    opencv-3.2.0-android-sdk下载

    4. `java`目录:包含了OpenCV Android包装器的Java源码,方便在Java层调用OpenCV功能。 5. `docs`目录:可能有API文档和其他技术文档,帮助开发者理解如何使用OpenCV的API。 6. `build.gradle`或类似文件:可能包含...

    Android-sceneform-android-sdk.zip

    Android-sceneform-android-sdk.zip,面向android的sceneform sdk,安卓系统是谷歌在2008年设计和制造的。操作系统主要写在爪哇,C和C 的核心组件。它是在linux内核之上构建的,具有安全性优势。

    Android设计模式系列(2)--SDK源码之观察者模式.pdf

    在Android SDK源码中,观察者模式被广泛应用于对象间的通信,例如数据变更时的通知机制。本文将深入探讨这种模式在Android中的应用,以AbstractCursor为例进行解析。 在观察者模式中,有两个关键角色:观察者...

    opencv-3.4.4-android-sdk/sdk/native/其他文件.zip

    opencv-3.4.4-android-sdk/sdk/native/3rdparty opencv-3.4.4-android-sdk/sdk/native/jni opencv-3.4.4-android-sdk/sdk/native/staticlibs

    Android SDK (SDK Platforms)-android-34.zip

    Android SDK (SDK Platforms)-android-34.zip 是一个包含了Android操作系统第34版本(也称为Android 13)开发所需平台工具的压缩包。这个压缩文件对于开发者来说至关重要,因为它提供了构建、测试和调试Android应用...

    Android SDK (SDK Platforms)-android-30.zip

    Android SDK (SDK Platforms)-android-30.zip 是一个包含了Android开发平台版本30的软件开发工具包,这是Android操作系统的一个重要组成部分,专为开发者提供,用于构建、测试和调试针对Android 11(API级别30)的...

    android-4.3-sdk android-sdk-4.3-platforms

    3. **开发工具**:Android SDK还包括一系列开发工具,如ADT(Android Developer Tools)、SDK Manager、AAPT(Android Asset Packaging Tool)和Dalvik Debug Monitor Service等,这些工具帮助开发者构建、调试和...

    Android SDK (SDK Platforms)-android-32.zip

    Android SDK (SDK Platforms)-android-32.zip 是一个包含了Android操作系统第32版本(也称为Android 13)平台开发工具的压缩包。这个压缩文件是Android开发者在构建、测试和调试针对Android 13应用时所必需的核心...

    Android studio sdk 源码 android-23

    Android Studio SDK源码分析——聚焦Android 23 Android Studio是Google官方推荐的Android应用程序开发集成开发环境(IDE),它提供了强大的工具集,包括代码编辑器、调试器、构建工具等,极大地提升了开发者的工作...

Global site tag (gtag.js) - Google Analytics