14.设计模式-备忘录模式

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

需求

游戏的某个场景,一游戏角色有生命力、攻击力、防御力等等数据,在打Boss前和后一定会不一样的,我们允许玩家如果感觉与Boss决斗的效果不理想可以让游戏恢复到决斗前。

代码

业务类

c 复制代码
#include <stdio.h>
#include <stdlib.h>

typedef struct RoleStateMemo {
    int vit;
    int atk;
    int def;
} RoleStateMemo;

RoleStateMemo *InitRoleStateMemo(int vit, int atk, int def) {
    RoleStateMemo *obj = (RoleStateMemo *)malloc(sizeof(RoleStateMemo));
    obj->atk = atk;
    obj->vit = vit;
    obj->def = def;
    return obj;
}

typedef struct PlayRole {
    int vit;
    int atk;
    int def;
    // 金币
    int gold;
    RoleStateMemo *(*saveState)(struct PlayRole *);
    void (*recoveryState)(struct PlayRole *, RoleStateMemo *);
    void (*stateDisplay)(struct PlayRole *);
    void (*fight)(struct PlayRole *);
} PlayRole;

RoleStateMemo *SaveState(PlayRole *obj) {
    RoleStateMemo *res = InitRoleStateMemo(obj->vit, obj->atk, obj->def);
    return res;
}

void RecoveryState(PlayRole *obj, RoleStateMemo *memo) {
    obj->vit = memo->vit;
    obj->atk = memo->atk;
    obj->def = memo->def;
    return;
}

void StateDisplay(PlayRole *obj) {
    printf("角色状态信息:\n");
    printf("生命值:%d\n", obj->vit);
    printf("攻击力:%d\n", obj->atk);
    printf("防御力:%d\n", obj->def);
    printf("金币:%d\n", obj->gold);
    printf("======end======\n");
}

void Fight(PlayRole *obj) {
    obj->vit = (obj->vit)/2;
    obj->def = (obj->def)/2;
    obj->gold += 100;
}

PlayRole *InitPlayRole() {
    PlayRole *obj = (PlayRole *)malloc(sizeof(PlayRole));
    obj->vit = 100;
    obj->atk = 10;
    obj->def = 10;
    obj->gold = 0;
    obj->saveState = SaveState;
    obj->recoveryState = RecoveryState;
    obj->stateDisplay = StateDisplay;
    obj->fight = Fight;
    return obj;
}

typedef struct RoleStateManager {
    RoleStateMemo *memo;
} RoleStateManager;

客户端

c 复制代码
int main() {
    // 大战BOSS前
    PlayRole *lixiaoyao = InitPlayRole();
    lixiaoyao->stateDisplay(lixiaoyao);
    // 保存进度
    RoleStateManager stateManager;
    stateManager.memo = lixiaoyao->saveState(lixiaoyao);
    // 大战
    lixiaoyao->fight(lixiaoyao);
    lixiaoyao->stateDisplay(lixiaoyao);
    // 恢复之前进度
    lixiaoyao->recoveryState(lixiaoyao, stateManager.memo);
    lixiaoyao->stateDisplay(lixiaoyao);
    return 0;
}

客户端打印:

text 复制代码
角色状态信息:
生命值:100
攻击力:10
防御力:10
金币:0
======end======
角色状态信息:
生命值:50
攻击力:10
防御力:5
金币:100
======end======
角色状态信息:
生命值:100
攻击力:10
防御力:10
金币:100
======end======

UML图

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

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

Caretaker(管理者,此处是RoleStateManager):负责保存好备忘录Memento,不能对备忘录的内容进行操作或检查。

总结

  • 备忘录模式使用场景?
    "Memento模式比较适用于功能比较复杂的,但需要维护或记录属性历史的类,或者需要保存的属性只是众多属性中的一小部分时,Originator可以根据保存的Memento信息还原到前一状态。"
相关推荐
阿闽ooo3 天前
中介者模式打造多人聊天室系统
c++·设计模式·中介者模式
小米4963 天前
js设计模式 --- 工厂模式
设计模式
逆境不可逃3 天前
【从零入门23种设计模式08】结构型之组合模式(含电商业务场景)
线性代数·算法·设计模式·职场和发展·矩阵·组合模式
驴儿响叮当20103 天前
设计模式之状态模式
设计模式·状态模式
电子科技圈3 天前
XMOS推动智能音频等媒体处理技术从嵌入式系统转向全新边缘计算
人工智能·mcu·物联网·设计模式·音视频·边缘计算·iot
徐先生 @_@|||4 天前
安装依赖三方exe/msi的软件设计模式
设计模式
希望_睿智4 天前
实战设计模式之访问者模式
c++·设计模式·架构
茶本无香4 天前
设计模式之十六:状态模式(State Pattern)详解 -优雅地管理对象状态,告别繁琐的条件判断
java·设计模式·状态模式
驴儿响叮当20104 天前
设计模式之备忘录模式
设计模式·备忘录模式
驴儿响叮当20104 天前
设计模式之迭代器模式
设计模式·迭代器模式