模式定义

备忘录(Memento): 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。

模式动机

  • 备忘录模式比较适用于功能比较复杂的,但需要维护或记录属性历史的类,或者需要保存的属性只是众多属性中的一小部分时,LieKong可以根据stateManager保存的BaseState信息换遇到前一状态。

UML类图

设计介绍

  • LieKong

    游戏角色,拥有属性BaseState。一个可以回到过去的技能UnleashSkills

  • BaseState

    封装任务状态:三维坐标和血量两个状态

  • StateManager

    记录角色前一个状态

源码实现

  • baseState.h
#ifndef BASESTATE_H
#define BASESTATE_H #include <QObject> class BaseState : public QObject
{
Q_OBJECT
public:
struct POSITION
{
int x;
int y;
int z;
};
explicit BaseState(QObject *parent = nullptr);
explicit BaseState(POSITION pos, int xl, QObject *parent = nullptr);
BaseState(const BaseState& state);
BaseState& operator=(const BaseState& state); void SetPositon(POSITION pos);
void SetXL(int xl);
void PrintState();
signals: public slots: private:
POSITION m_Position;//位置
int m_Xl;//血量
}; #endif // BASESTATE_H
  • baseState.cpp
#include <QDebug>
#include "basestate.h" BaseState::BaseState(QObject *parent)
{ } BaseState::BaseState(POSITION pos, int xl, QObject *parent)
: QObject(parent), m_Position(pos), m_Xl(xl)
{ } BaseState::BaseState(const BaseState &state)
{
if(this != &state)
{
this->m_Xl = state.m_Xl;
this->m_Position.x = state.m_Position.x;
this->m_Position.y = state.m_Position.y;
this->m_Position.z = state.m_Position.z;
}
} BaseState &BaseState::operator=(const BaseState &state)
{
if(this != &state)
{
this->m_Xl = state.m_Xl;
this->m_Position.x = state.m_Position.x;
this->m_Position.y = state.m_Position.y;
this->m_Position.z = state.m_Position.z;
}
return *this;
} void BaseState::SetPositon(POSITION pos)
{
m_Position.x = pos.x;
m_Position.y = pos.y;
m_Position.z = pos.z;
} void BaseState::SetXL(int xl)
{
m_Xl = xl;
} void BaseState::PrintState()
{
qDebug() << QString("现在的坐标是:x = %1, y = %2, z = %3;").arg(m_Position.x).arg(m_Position.y).arg(m_Position.z);
qDebug() << QString("现在的血量是:%1").arg(m_Xl);
qDebug() << endl;
}
  • liekong.h
#ifndef LIEKONG_H
#define LIEKONG_H #include <QObject>
#include <functional>
#include "basestate.h" using skill1 = std::function<bool (int)>;
using skill2 = std::function<void(void)>;
using skill3 = std::function<void(void)>; class Liekong : public QObject
{
Q_OBJECT
public:
explicit Liekong(QObject *parent = nullptr);
BaseState State();
void SetState(BaseState state); void UnleashSkills(const skill1& skill);//释放时光倒回技能
void ChangeState();//改变状态
private:
BaseState CreateState(); signals: public slots:
private:
BaseState m_State;
}; #endif // LIEKONG_H
  • liekong.cpp
#include <QDebug>
#include "liekong.h" Liekong::Liekong(QObject *parent) : QObject(parent)
{
CreateState();
} BaseState Liekong::State()
{
m_State.PrintState();
return m_State;
} void Liekong::SetState(BaseState state)
{
m_State= state;
} BaseState Liekong::CreateState()
{
BaseState::POSITION pos;
pos.x = 20;
pos.y = 50;
pos.z = 67;
m_State = BaseState(pos, 100);
return m_State;
} void Liekong::UnleashSkills(const skill1& skill)
{
int a = 0;
skill(a);
} void Liekong::ChangeState()
{
BaseState::POSITION pos;
pos.x = 10;
pos.y = 10;
pos.z = 10;
m_State.SetPositon(pos);
m_State.SetXL(10);
}
  • statemanager.h
#ifndef STATEMANAGER_H
#define STATEMANAGER_H #include <QObject>
#include "basestate.h" class StateManager : public QObject
{
Q_OBJECT
public:
explicit StateManager(QObject *parent = nullptr); void SetState(const BaseState& state);
BaseState State(); signals:
public slots: private:
BaseState m_State;
}; #endif // STATEMANAGER_H
  • satemanager.cpp
#include "statemanager.h"

StateManager::StateManager(QObject *parent) : QObject(parent)
{ } void StateManager::SetState(const BaseState& state)
{
m_State = state;
} BaseState StateManager::State()
{
return m_State;
}
  • main.cpp
/************************************
* @brief : 需要三个类,我们以 守望先锋 里的裂空的一个回到去过去的技能为背景写一个实现
* @author : wzx
* @date : 2020-04-30
* @project : Memento
*************************************/
#include <QCoreApplication>
#include <QDebug>
#include "liekong.h"
#include "statemanager.h" int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv); Liekong lk;
qDebug() << "初始状态:";
BaseState state = lk.State(); StateManager manage;
manage.SetState(state); lk.ChangeState();
qDebug() << "更新后状态:";
lk.State(); BaseState state1 = manage.State(); lk.UnleashSkills([&lk, state1](int a){
lk.SetState(state1);
qDebug() << "param = " << a;
return true;
});
qDebug() << "还原后状态:";
lk.State(); return a.exec();
}
  • 运行结果

初始状态:

"现在的坐标是:x = 20, y = 50, z = 67;"

"现在的血量是:100"

更新后状态:

"现在的坐标是:x = 10, y = 10, z = 10;"

"现在的血量是:10"

还原后状态:

"现在的坐标是:x = 20, y = 50, z = 67;"

"现在的血量是:100"

优点

  • 封装细节,如果要更改保存的细节,也不会影响到客户端

缺点

备忘录模式 (c++实现)的更多相关文章

  1. MementoPattern(备忘录模式)

    /** * 备忘录模式 * @author TMAC-J * 用于存储bean的状态 */ public class MementoPattern { public class Memento{ pr ...

  2. C#设计模式-备忘录模式

    访问者模式的实现是把作用于某种数据结构上的操作封装到访问者中,使得操作和数据结构隔离.而本文要介绍的备忘者模式与命令模式有点相似,不同的是,命令模式保存的是发起人的具体命令(命令对应的是行为),而备忘 ...

  3. C#设计模式系列:备忘录模式(Memento)

    1.备忘录模式简介 1.1>.定义 备忘录模式在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可以将该对象恢复到原先保存的状态. 1.2>.使用频率 ...

  4. php实现设计模式之 备忘录模式

    <?php /*备忘录模式:在不破坏封装的前提下,获取对象的内部状态,并且在对象外保存该状态.这样就可以将该对象恢复到保存之前的状态(行为模式) * * 发起人:记录当前时刻的内部状态,负责定义 ...

  5. java设计模式之备忘录模式

    备忘录模式 备忘录模式是一种软件设计模式:在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态.一听到备忘录这个字的时候想起了小小时打的游 ...

  6. 备忘录模式(Memento Pattern)

    在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态. 备忘录模式主要思想是——利用备忘录对象来对保存发起人的内部状态,当发起人需要恢复原 ...

  7. C++设计模式-Memento备忘录模式

    Memento模式作用:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可将该对象恢复到原先保存的状态. UML图: Originator:负责创建一个备忘录Me ...

  8. C++设计模式-备忘录模式(1)

    备忘录模式:备忘录对象时一个用来存储另外一个对象内部状态的快照对象. 备忘录模式的用意是在不破坏封装的条件下,将一个对象的状态捉住并外部化,存储起来从而可以在将来合适的时候把这个对象还原到存储起来的状 ...

  9. JAVA 设计模式 备忘录模式

    用途 备忘录模式 (Memento) 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态. 这样以后就可将该对象恢复到原先保存的状态. 备忘录模式是一种行为型模式. 结构

  10. 【GOF23设计模式】备忘录模式

    来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_备忘录模式.多点备忘.事务操作.回滚数据底层架构 package com.test.memento; /** * 源发器类 ...

随机推荐

  1. 教你用Cobra开发类似docker的命令行

    目录 前言 一.安装 二.初始化应用 gomod初始化 创建入口文件cmd/root.go 创建主程序main.go 三.生成Command 创建hello子命令 创建version子命令 四.如何设 ...

  2. Blazor入门笔记(2)-分部类组件与组件的继承

    1.前言 本文接自Blazor的组件(1)-从0构建一个组件 2.分部类组件 Razor组件你可理解为就是一个类名与文件名相同的类,因此,可以新建一个同名的partial类,将组件中@code里面的代 ...

  3. Azure安装win2016的服务器,并下载安装mysql数据库心得

    随便写写 第一部分:新建虚拟机创建win2016服务器 这部分内容跟着微软云提示操作即可, 基本步骤:创建一堆名字,选择一个地区的服务器,配置一些基本信息,然后azure就会自动创建虚拟机并安装你选择 ...

  4. 多线程学习笔记(五)---- 在JDK文档的使用

    1.前言 我们经常在JDK文档中见到一些类上的介绍说,该类是"安全的"."不安全"."效率高"."效率低"的词眼.这里, ...

  5. C语言:static关键字用法

    参考博客:https://blog.csdn.net/guotianqing/article/details/79828100 看个例子: #include <stdio.h> void ...

  6. Mac 系统root

    没错,你没看错,就是root mac系统安装件的时候,你有没有遇到过这种情况 总之,就是安装不上软件,肿么办? 网上解觉办法是: 进入系统偏好设置,设置为允许任何人,可是进去后这样: 别着急,打开命令 ...

  7. vue中axios的安装使用

    axios是一个基于 promise 的 HTTP 库,在vue中axios是比较常用的网络请求方法. 安装 npm install axios -S 在main.js配置 import axios ...

  8. C#多线程系列(2):多线程锁lock和Monitor

    1,Lock lock 原型 lock 编写实例 2,Monitor 怎么用呢 解释一下 示例 设置获取锁的时效 C# 中,可以使用 lock 关键字和 Monitor 类来解决多线程锁定资源和死锁的 ...

  9. 004-流程控制-C语言笔记

    004-流程控制-C语言笔记 学习目标 1.[掌握]关系运算符和关系表达式 2.[掌握]逻辑运算符和逻辑表达式 3.[掌握]运算符的优先级和结合性 4.[掌握]if-else if-else结构的使用 ...

  10. AJ学IOS(22)UI之UIApplicationDelegate和UIWindow

    AJ分享,必须精品 UIApplicationDelegate 每次新建完项目,都有个带有“AppDelegate”字眼的类,它就是UIApplication的代理 NYAppDelegate默认已经 ...