鼠扑 发表于 2025-11-21 17:37:08

项目优化之备忘录模式

目次
根本概念:
动机:
界说:
代码举例:
备忘录状态类:
元发起类:
备忘录管理类:
调用示例:
停车场项目中使用
标题配景
代码举例
车道备忘录状态类:
车道备忘录管理类
车道设置类:

根本概念:

动机:

        在软件构建过程中某些对象的状态在转换过程中由于某种必要要求步伐可以回溯到之前对象某个所处的状态;如文档编辑器的打消动作、游戏的存档等。

界说:

        在不粉碎封装性的条件下,捕捉一个对象的内部状态,并在该对象之外生存这个状态,以便于在差异机遇可以切换到差异的状态中。

代码举例:

备忘录状态类:

        形貌元发器全部大概变革的状态的类,这里以string字符串记载(现实中对象常可很方便的序列化)。
//备忘录状态类
class Memento
{
        string state;
        //..
public:
        Memento(const string & s) : state(s) {}
        string getState() const { return state; }
        void setState(const string & s) { state = s; }
}; 元发起类:

        业务类,会有状态变革,在必要记载当前状态时可以Memento*createMemento()创建当前状态供备忘录管理类记载,在必要规复某一状态时可以通过restoreMemento(Memento*m)规复状态m。
//业务中 元发器
class Originator
{
        string state;
        //....
public:
        Originator() {}
        ~Originator(){}
        //业务相关函数 会修改当前状态state
        /*
        ...
        */

        //创建备忘录记录
        Memento* createMemento() {
                return new Memento(state);
        }
        //恢复备忘录
        void restoreMemento(Memento*m)
        {
                state = m->getState();
        }

}; 备忘录管理类:

        记载元发器创建的状态,在元发器业务必要规复某一状态时提供状态便于其规复。
class MemManager
{
public:
        MemManager() {};
        ~MemManager() {
                for (auto iter = m_MementoVec.begin(); iter != m_MementoVec.end(); iter++)
                {
                        delete (*iter);
                }
        }
        void setMomento(Memento* m) {
                m_MementoVec.push_back(m);
        }

        Memento* getMemento(int index)
        {
                return m_MementoVec.at(index);
        }

        Memento* getLastMemento()
        {
                return m_MementoVec.at(m_MementoVec.size() - 1);
        }

private:
        vector<Memento*>m_MementoVec;
}; 调用示例:

int main()
{
        Originator orginator;
        MemManager memManger;
        //捕获对象状态,存储到备忘录
        memManger.setMomento(orginator.createMemento());

        //... 改变orginator状态
        memManger.setMomento(orginator.createMemento());
        //... 改变orginator状态

        //从备忘录中恢复最初状态
        orginator.restoreMemento(memManger.getMemento(0));

        //恢复最近一次备忘录 撤销操作
        orginator.restoreMemento(memManger.getLastMemento());
} 停车场项目中使用

标题配景

        在停车项目中有许多场景共用一个界面,但是在差异状态下必要切换表现不通的参数设置,如多个车道可以共用一个车道设置界面,各个车道的设置由于收支口、收费与否、音量巨细、过车规则等等设置各异,但是车道的设置界面一样可共用。此时使用备忘录模式举行优化操持,当车道切换时记载当前车道的状态(设置参数),同时还原切到的车道的状态(设置参数);如许就可以在一个设置界面上设置表现多个车道设置信息。
代码举例

车道备忘录状态类:

        现在项目中大部门类通过Qt的反射,自界说实现了json的序列化和反序列化,因此车道状态用字符串记载,方便存储与查验变动等。
//备忘录状态类
class MemLaneCfg
{
        string laneCfgStr;
        //..
public:
        MemLaneCfg(const string & s) : laneCfgStr(s) {}
        string getLaneCfg() const { return laneCfgStr; }
        void setLaneCfg(const string & s) { laneCfgStr = s; }
}; 车道备忘录管理类

#define g_LaneCfgMemHelper Singleton<LaneCfgMemManager>::getInstance()
class LaneCfgMemManager
{
        friend Singleton<LaneCfgMemManager>;
public:       
        void setLaneCfgMomento(const string&laneCodeStr, std::shared_ptr<MemLaneCfg> memCfg) {
                m_laneCode2Mem = memCfg;
        }

        std::shared_ptr<MemLaneCfg> getLaneCfgByLaneCode(const string&laneCodeStr)
        {
                if (m_laneCode2Mem.find(laneCodeStr)!= m_laneCode2Mem.end())
                {
                        return m_laneCode2Mem.at(laneCodeStr);
                }
                return nullptr;
        }
private:
        unordered_map<string,std::shared_ptr<MemLaneCfg>>m_laneCode2Mem;
        LaneCfgMemManager() {};
        ~LaneCfgMemManager() {
        }
};
车道设置类:


        该类在车道生存时会触发当前车道设置备忘录的存储,在车道切换时会触发切换后车道设置备忘录的革新。
class QLaneConfig : public QFrame
{
        Q_OBJECT
public:
        QLaneConfig(QWidget *parent = Q_NULLPTR);
        ~QLaneConfig();
        /*
        ...
        */

private:
        //创建当前车道的备忘录
        std::shared_ptr<MemLaneCfg>createMemento() {
                ScreenConfig::LaneDisplayDto laneDtoDate;
                /*
                根据界面配置信息填充laneDtoDate
                ...
                */
                string laneCfgStr = laneDtoDate.toJson();//序列化
                return std::make_shared<MemLaneCfg>(new MemLaneCfg(laneCfgStr));
        }

        //恢复指定车道备忘录
        void restoreMemento(const string laneCodeStr)
        {
                auto laneCfgMemPtr = g_LaneCfgMemHelper->getLaneCfgByLaneCode(laneCodeStr);
                string laneCfgStr = laneCfgMemPtr->getLaneCfg();
                ScreenConfig::LaneDisplayDto laneDtoDate;
                if (0 == dtoLane.ConvertBy(laneCfgStr))//反序列化得到车道对象
                {
                        //配置刷新车道界面各个参数
                }
        }
        /*
        ...
        */

private slots:
        //切换车道槽函数
        void switchLaneSlots(const string&laneCodeStr)
        {
                restoreMemento(laneCodeStr);
        }
        //保存当前配置信息
        void on_btnApply_clicked()
        {
                auto cfgMemPtr = createMemento();
                g_LaneCfgMemHelper->setLaneCfgMomento(m_laneCodeStr, cfgMemPtr);
                //数据库存储当前车道配置
                //...
        }
private:
        bool aboutToSave(bool onlyCheck, string &strErrorMsg); // 缓存界面配置信息
        /*
        ...
        */
};

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 项目优化之备忘录模式