通常,我们对class 的定义为一个可以抽象的实物,就像书上说的那个什么人呀,车呀 ,其实这是对class 的一个片面的理解。
然后我们再来看看对class 的定义:数据与数据操作的一个集合体。
从这个定义中我们不难看出有两个关键的东西,一是数据,一是动作。而我们通常强调的是数据为主体,以动作为辅的一种class结构。其实在很多情况下,以动作为主往往比以数据为主要清晰的多。
说一个很简单的类子
Undo & Redo
在我们编写一个程序的时候,这个功能往往是少不了的,随着功能的复杂,那么Undo Redo也会变得很难控制,这里我就利用以动作为主设计一套比较合理的Undo Redo 机制
Undo & Redo 基类class CAction : public CObject{public: CAction(BOOL inAlreadyDone = false, const CString& strRedoString = "", const CString& strUndoString = ""); virtual ~CAction();
virtual void Finalize(); virtual void Redo(); // Also functions as "Do" virtual void Undo(); BOOL IsDone() const { return m_IsDone; }; virtual BOOL IsPostable() const; virtual BOOL CanRedo() const; virtual BOOL CanUndo() const; virtual void GetDescription( CString& strRedoString, CString& strUndoString) const;
protected: CString m_strRedoString; CString m_strUndoString; BOOL m_IsDone; // Is Action done or redone?
// Pure Virtual functions. Subclasses must override! virtual void RedoSelf() = 0; virtual void UndoSelf() = 0;};
从基类派生出来到一个Undo 动子class CZoomAction : public CAction {public: CZoomAction(CDrawPicView * pView,float nFactor); virtual ~CZoomAction();
protected: CDrawPicView* m_pView; float m_nOld; float m_nNew;
protected: virtual void RedoSelf() ; virtual void UndoSelf() ;};
管理整个Undo Redo 系统class CUndoer {public: void AddAction(CAction * pAction); BOOL GetUndoStatus()const; BOOL GetRedoStatus()const; void Redo(); void Undo();
CUndoer(); virtual ~CUndoer();
protected: CObList* m_pActionList; int m_nCurrentUndoIndex; int m_nCurrentRedoIndex;};当一个动作发生的时候 CZoomAction * pZoom = new CZoomAction(this,nFact); m_Undoer.AddAction(pZoom);当需要Undo 的时候 m_Undoer.Undo();
当控制menu 状态的时候 pCmdUI->Enable(m_Undoer.GetRedoStatus()); pCmdUI->Enable(m_Undoer.GetUndoStatus());
这样,如果你的那个window需要实现Undo & Redo 那么只需要包含CUndoer 的一个对象,然后就是针对每个需要Undo & Redo 的动作从CAction 派生出一个类,这个类将包含这个Action所需要的相关数据,并且同时实现 Undo Redo 的具体动作,如果中间有临时申请内存变量,可以在这个CAction 析构的时候释放。这样设计的好处是: 将动作独立出来形成一个class 将Redo and Undo 放在同一个class中,比较清楚
减轻Window 的负担(将大部分动作全部封装到对应的Action class 中,windows 本事就只需要负责一些UI 上的动作) 可以集中管理Redo and Undo