栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++备忘录模式,状态模式(19,20)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++备忘录模式,状态模式(19,20)

备忘录模式 什么是备忘录模式

备忘录模式是一种行为设计模式, 允许在不暴露对象实现细节的情况下保存和恢复对象之前的状态。(浏览器回退、编辑器撤销与重做、虚拟机生成快照与恢复、游戏悔棋等)

为什么使用备忘录模式

备忘录模式允许你复制对象中的全部状态 (包括私有成员变量), 并将其独立于对象进行保存。 尽管大部分人因为 “撤销” 这个用例才记得该模式, 但其实它在处理事务 (比如需要在出现错误时回滚一个操作) 的过程中也必不可少;备忘录让对象自行负责创建其状态的快照。 任何其他对象都不能读取快照, 这有效地保障了数据的安全性

备忘录模式实现步骤

1.提供一个原发器类:真正要被保存或恢复的对象,其负责创建一个备忘录,可以存储、恢复需要状态信息

2.提供一个备忘录类:用于存储原生器对象的的内部状态,防止外部直接访问原生器对象

3.提供一个管理者类:负责存储备忘录,但不能对备忘录内容进行操作和访问,只能将备忘录传递给其他对象  

//下棋退步问题
#include 
#include 
#include 
using namespace std;
class Memento {
   public:
    Memento(string name, pair pos) : name(name), pos(pos) {}
    string GetName() { return name; }
    pair GetPos() { return pos; }
    void Show() {
        cout << name << ":(" << pos.first << "," << pos.second << ")" << endl;
    }

   private:
    string name;
    pair pos;
};
class Chess {
   public:
    Chess(string name, pair pos) : name(name), pos(pos) {}
    void SetChess(string name, pair pos) {
        this->name = name;
        this->pos = pos;
    }
    Memento* SaveState() { return new Memento(name, pos); }
    void Restore(Memento* memento) {
        name = memento->GetName();
        pos = memento->GetPos();
    }

   protected:
    string name;
    pair pos;
};

class Caretaker {
   public:
    //存档
    void AddMento(Memento* memento) {
        mementos.push_back(memento);
        step++;
    }
    //获取存档
    Memento* GetMemento(int index) {
        step = index;
        return mementos[step];
    }
    void Show() {
        for (int i = 0; i < step; i++) {
            cout << "step:" << i + 1 << "手" << endl;
            mementos[i]->Show();
        }
    }

   protected:
    vector mementos;
    static int step;
};
int Caretaker::step = 0;

int main() {
    Chess* pc = new Chess("车", {4, 3});
    Caretaker* pcaretaker = new Caretaker;
    pcaretaker->AddMento(pc->SaveState());
    pcaretaker->Show();

    cout << endl;
    pc->SetChess("马", {8, 8});
    pcaretaker->AddMento(pc->SaveState());
    pcaretaker->Show();

    cout << endl;
    pc->SetChess("炮", {6, 6});
    pcaretaker->AddMento(pc->SaveState());
    pcaretaker->Show();
    cout << endl;
    pc->Restore(pcaretaker->GetMemento(2));
    pcaretaker->Show();

    return 0;
}
备忘录模式优缺点

优点

  • 你可以在不破坏对象封装情况的前提下创建对象状态快照

  • 你可以通过让负责人维护原发器状态历史记录来简化原发器代码

缺点

  • 如果客户端过于频繁地创建备忘录, 程序将消耗大量内存

  • 负责人必须完整跟踪原发器的生命周期, 这样才能销毁弃用的备忘录

状态模式 什么是状态模式

状态模式是一种行为设计模式, 让你能在一个对象的内部状态变化时改变其行为, 使其看上去就像改变了自身所属的类一样

为什么使用状态模式

模式建议你将所有特定于状态的代码抽取到一组独立的类中。 这样一来, 你可以在独立于其他状态的情况下添加新状态或修改已有状态, 从而减少维护成本;状态模式让你能够生成状态类层次结构, 通过将公用代码抽取到抽象基类中来减少重复

状态模式实现步骤

1.提供一个上下文环境类:抽象一个客户程序需要的接口,将与状态相关的操作委托给当前的具体状态类对象来处理

2.提供一个抽象给状态类:定义一个接口以封装使用上下文环境的的一个特定状态相关的行为

3.提供一个具体状态类:实现抽象状态定义的接口

//
#include 
using namespace std;
class Context;
class AbstractState {
   public:
    virtual void Handle(Context* p) = 0;
};
class ConcreteStateA : public AbstractState {
    void Handle(Context* p) { cout << "A....." << endl; }
};
class ConcreteStateB : public AbstractState {
    void Handle(Context* p) { cout << "B....." << endl; }
};

class Context {
   public:
    Context(AbstractState* pstate) : pstate(pstate) {}
    void Requst() {
        if (pstate) {
            pstate->Handle(this);
        }
    }
    void ChangeState(AbstractState* pstate) { this->pstate = pstate; }

   private:
    AbstractState* pstate;
};

int main() {
    AbstractState* pA = new ConcreteStateA;
    AbstractState* pB = new ConcreteStateB;
    Context* pC = new Context(pA);
    pC->Requst();
    pC->ChangeState(pB);
    pC->Requst();
    return 0;
}
状态模式优缺点

优点

  • 单一职责原则: 将与特定状态相关的代码放在单独的类中

  • 开闭原则: 无需修改已有状态类和上下文就能引入新状态

  • 通过消除臃肿的状态机条件语句简化上下文代码

缺点

  • 如果状态机只有很少的几个状态, 或者很少发生改变, 那么应用该模式可能会显得小题大作

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1004771.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号