一个实现恢复删除机制(do undo)的设计
来源:互联网 发布:淘宝网上卖什么赚钱 编辑:程序博客网 时间:2024/06/09 15:33
BaseOperation.h
/*----------------------------------------------------------
desc : 编辑器中各种操作的接口类。
author : zilong
version : 1.0
date : 2011-03-23
revision:
----------------------------------------------------------*/
#pragma once
class IBaseOperation
{
public:
IBaseOperation(void);
virtual ~IBaseOperation(void);
//每个operation应该保证在没有成功的情况下自己回滚(即不改变数据库)。
virtual bool Excute(void) = 0;
void SetStatus(bool bExcuted_);
protected:
bool m_bExcuted;
};
//一对相反的操作
class COpertaionPair
{
public:
COpertaionPair(IBaseOperation *do_, IBaseOperation *undo_);
~COpertaionPair();
//回滚本操作,即本操作执行前的状态。
bool Rollback(void);
//执行本操作
bool Excute(void);
//本操作是否已执行
bool IsExcuted(void){return m_bExcuted;};
private:
IBaseOperation *m_do;
IBaseOperation *m_undo;
bool m_bExcuted; //true, 已执行;false, 处于回滚后的状态。
};
BaseOperation.cpp
#include "BaseOperation.h"
#include <stdlib.h>
#include <assert.h>
IBaseOperation::IBaseOperation(void):
m_bExcuted(false)
{
}
IBaseOperation::~IBaseOperation(void)
{
}
void IBaseOperation::SetStatus(bool bExcuted_)
{
m_bExcuted = bExcuted_;
}
COpertaionPair::COpertaionPair(IBaseOperation *do_, IBaseOperation *undo_):
m_do(do_),
m_undo(undo_),
m_bExcuted(false)
{
}
COpertaionPair::~COpertaionPair()
{
}
bool COpertaionPair::Rollback(void)
{
assert(m_undo != NULL);
if(!m_bExcuted)
return false;
m_bExcuted = false;
/*
return m_undo->Excute();
*/
bool ret = m_undo->Excute();
if(ret)
{
m_undo->SetStatus(true);
m_do->SetStatus(false);
}
return ret;
}
bool COpertaionPair::Excute(void)
{
assert(m_do != NULL);
if(m_bExcuted)
return false;
m_bExcuted = true;
/*
return m_do->Excute();
*/
bool ret = m_do->Excute();
if(ret)
{
m_do->SetStatus(true);
m_undo->SetStatus(false);
}
return ret;
}
RecoveryManager.h
/*----------------------------------------------------------
desc : 恢复功能(undo redo)模块。
author : zilong
version : 1.0
date : 2011-03-23
revision:
----------------------------------------------------------*/
#pragma once
#include <stack>
class COpertaionPair;
class CRecoveryManager
{
private:
typedef std::stack<COpertaionPair *> TOperations;
public:
CRecoveryManager(void);
~CRecoveryManager(void);
//清空库
void Clear(void);
//是否可以回滚
bool CanRollback(void);
//是否可以向前滚动
bool CanRoll(void);
//执行一个操作,成功之后将该操作入库。
bool Excute(COpertaionPair *operation_);
//回滚一个操作。
bool Rollback(void);
//向前滚动一个操作。
bool Roll(void);
bool Rollback(int count_);
bool Roll(int count_);
private:
void ClearOpertaions(TOperations &_ops_);
private:
TOperations m_undoes; //
TOperations m_redoes;
};
RecoveryManager.cpp
#include "RecoveryManager.h"
#include "rollback\BaseOperation.h"
#include <assert.h>
CRecoveryManager::CRecoveryManager(void)
{
}
CRecoveryManager::~CRecoveryManager(void)
{
Clear();
}
void CRecoveryManager::Clear(void)
{
ClearOpertaions(m_redoes);
ClearOpertaions(m_undoes);
}
void CRecoveryManager::ClearOpertaions(TOperations &_ops_)
{
while(!_ops_.empty())
{
delete _ops_.top();
_ops_.pop();
}
}
bool CRecoveryManager::CanRollback(void)
{
return !m_undoes.empty();
}
bool CRecoveryManager::CanRoll(void)
{
return !m_redoes.empty();
}
bool CRecoveryManager::Excute(COpertaionPair *operation_)
{
assert(operation_ != NULL);
if(NULL == operation_)
return false;
if(operation_->Excute())
{
ClearOpertaions(m_redoes);
m_undoes.push(operation_);
return true;
}
return false;
}
bool CRecoveryManager::Rollback(void)
{
if(!CanRollback())
return false;
COpertaionPair *op = m_undoes.top();
assert(op != NULL);
if(op->Rollback())
{
m_undoes.pop();
m_redoes.push(op);
return true;
}
return false;
}
bool CRecoveryManager::Roll(void)
{
if(!CanRoll())
return false;
COpertaionPair *op = m_redoes.top();
assert(op != NULL);
if(op->Excute())
{
m_redoes.pop();
m_undoes.push(op);
return true;
}
return false;
}
举个例子。例如,要写一个文本编辑器, 其中要实现一个删除操作, 且可以实现undo, redo.
class CDeleteTextOper: public IBaseOperation
{
public:
CDeleteTextOper(CTextDataMgr *receiver);
virtual ~CDeleteTextOper(void);
virtual bool Excute(void)
{
m_pReceiver->DeleteText(m_head, m_tail);
}
void SetData(int head, int tail);
protected:
CTextDataMgr *m_pReceiver;
int m_head;
int m_tail;
};
class CAddTextOper: public IBaseOperation
{
public:
CAddTextOper(CTextDataMgr *receiver);
virtual ~CAddTextOper(void);
virtual bool Excute(void)
{
m_pReceiver->AddText(m_offset, txt);
}
void SetData(int offset, const std::string &txt);
protected:
CTextDataMgr *m_pReceiver;
int m_offset;
std::string txt;
};
class CTextDataMgr
{
private:
CRecoveryManager m_opManager;
public:
std::string GetText(int head, int tail);
public:
bool AddText(int offset, const std::string &txt);
bool DeleteText(int head, int tail);
public:
bool DoDeleteText(int head, int tail)
{
CDeleteTextOper *mydo = new CDeleteTextOper(this);
mydo->SetData(head, tail);
CAddTextOper *undo = new CAddTextOper(this);
undo->SetData(head, this->GetText(head, tail));
COpertaionPair *op = new COpertaionPair(mydo, undo);
return m_opManager.Excute(op);
}
public:
virtual void Redo(void)
{
m_opManager.Roll();
}
virtual void Undo(void)
{
m_opManager.Rollback();
}
virtual bool CanRedo(void);
virtual bool CanUndo(void);
};
客户端调用代码如下
void main()
{
CTextDataMgr dataMgr;
//……
//执行操作
dataMgr.DoDeleteText(10, 20);
//undo
dataMgr.Undo();
//redo
dataMgr.Redo();
}
- 一个实现恢复删除机制(do undo)的设计
- 发现一个vim的恢复命令undo
- WebKit Undo实现机制
- undo数据文件丢失的恢复
- 直接删除undo及temp表空间文件后的数据库恢复一例
- 设计模式:Command模式 实现无限次的undo、redo
- 一个关于如何实现Redo和Undo的系列
- Confluence 恢复一个已经删除的页面
- undo丢失的简单不完全恢复
- 【undo表空间的丢失-恢复-1】
- 设计和实现一个简单的hdfs的备份恢复与容灾系统(1)
- 使用设计模式实现Undo,Redo框架
- 关于undo机制的总结[收集中]
- 浅谈emacs的撤销undo机制
- 利用swing的undo包实现Undo/Redo功能
- oracle undo segments, do blocks
- 如何在 Linux 中恢复一个删除了的文件
- oracle11g dataguard undo恢复
- linux常用系统性能监控工具
- LINUX驱动分析之RTC(一)
- c++ 中关于引用(1)
- 查RPM包的网站
- android JNI
- 一个实现恢复删除机制(do undo)的设计
- java 中的final解析
- LINUX驱动分析之RTC(二)
- Trie树(oversimplified python version)
- 静态成员函数
- LINUX驱动分析之RTC(三)
- PHP获取星期的方法及代码
- 关于iOS应用设计的一些最佳实践
- hdu 4347 【KD-TREE】