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信息还原到前一状态。"
相关推荐
J_liaty15 小时前
23种设计模式一代理模式
设计模式·代理模式
苏渡苇21 小时前
优雅应对异常,从“try-catch堆砌”到“设计驱动”
java·后端·设计模式·学习方法·责任链模式
短剑重铸之日1 天前
《设计模式》第十一篇:总结
java·后端·设计模式·总结
feasibility.1 天前
AI 编程助手进阶指南:从 Claude Code 到 OpenCode 的工程化经验总结
人工智能·经验分享·设计模式·自动化·agi·skills·opencode
BD_Marathon1 天前
七大设计原则介绍
设计模式
YigAin1 天前
Unity23种设计模式之 享元模式
设计模式·享元模式
范纹杉想快点毕业2 天前
实战级ZYNQ中断状态机FIFO设计
java·开发语言·驱动开发·设计模式·架构·mfc
茂桑2 天前
DDD领域驱动设计-基础设施层
设计模式·架构
小温冲冲2 天前
通俗且全面精讲工厂设计模式
设计模式
进击的小头2 天前
设计模式与C语言高级特性的结合
c语言·设计模式