这是我在CodeGuru上看到的令人惊艳的代码。(http://www.codeguru.com/misc/undo_redo_cdocument.shtml)。class CUndo {
private:
CObList m_undolist; // Stores undo states
CObList m_redolist; // Stores redo states
long m_growsize; // Adjust for faster saves
long m_undoLevels; // Requested Undolevels 
long m_chkpt; void AddUndo(CMemFile*);
void AddRedo(CMemFile *pFile); 
void Load(CMemFile*);
void Store(CMemFile*);
void ClearRedoList();

public: // Here are the hooks into the CDocument class
virtual void Serialize(CArchive& ar) = 0;
virtual void DeleteContents() = 0; // User accessable functions
CUndo(long undolevels = 4, long = 32768); // Constructor
~CUndo(); // Destructor
BOOL CanUndo(); // Returns TRUE if can Undo
BOOL CanRedo(); // Returns TRUE if can Redo
void Undo(); // Restore next Undo state
void Redo(); // Restore next Redo state
void CheckPoint(); // Save current state 
void EnableCheckPoint();
void DisableCheckPoint();
};只要你的应用程序文档类从这个CUndo类派生,可以给SDI/MDI应用程序添加UNDO/REDO的功能。
例如这样:class CMyDoc : public CDocument, public CUndo{};它使用的实现技巧是利用CMyDoc::Serialize()虚函数保存文档实例的状态,virtual void Serialize(CArchive& ar)=0的声明迫使子类一定要实现它;我之所以惊叹这段码,并不是它使用的实现技巧,而是它的采用的设计模式。虽说可以归纳为Command模式的范畴。动态地给一个类添加功能;父类的实现(Undo/Redo)依赖子类的具体实现(CMyDoc::Serialize);
接口和实现的分离,难道就没有Decorator(装饰)Bridge(桥接)的影子?解脱之味不独饮!