上一篇講了用COMMAND模式設計基本骨架,傳送門:C++基礎——模擬事務(1)COMMAND模式 這裡將繼續使用Composite模式,以使事務可以嵌套。
=================================版權聲明=================================
版權聲明:原創文章 禁止轉載
請通過右側公告中的“聯繫郵箱([email protected])”聯繫我
勿用於學術性引用。
勿用於商業出版、商業印刷、商業引用以及其他商業用途。
本文不定期修正完善。
本文鏈接:http://www.cnblogs.com/wlsandwho/p/5160380.html
恥辱牆:http://www.cnblogs.com/wlsandwho/p/4206472.html
=======================================================================
因為要用到好多設計模式,所以我把原文拆成幾部分,每部分講解一個設計模式。wlsandwho王林森
(這意味著還有一篇。)
=======================================================================
上一篇講了用COMMAND模式設計基本骨架,傳送門:C++基礎——模擬事務(1)COMMAND模式
這裡將繼續使用Composite模式,以使事務可以嵌套。wlsandwho王林森
=======================================================================
下麵該去考慮如何實現“嵌套事務”了。wlsandwho王林森
想要一個事務像一個任務一樣,被添加到另一個事務里,並且能任意的組合,形成一個樹形的結構,好像composite模式比較合適。
四人幫的典型的composite對象結構圖我就不畫了,composite結構圖我也不畫了。wlsandwho王林森
事務要想擁有任務的功能,最簡單的方法是事務類繼承任務類。考慮到單繼承、多繼承之爭,我採用單繼承實現。
大致結構圖如下。wlsandwho王林森
如此一來,CTransactionBase有了CTaskBase的介面。wlsandwho王林森
回顧一下CTask的兩個介面,一個是Do,Do里執行Doing,另一個Undo,Undo里執行Undoing。Doing和Undoing是用Set函數進行手工設置綁定的。
CTransactionBase繼承此介面後,Do里執行Commit,Undo里執行Rollback。Commit和Rollback是CTransactionBase的保護成員函數。不需要手工設置。
下麵上第三版代碼。wlsandwho王林森
=======================================================================
1 #include <iostream> 2 #include <list> 3 #include <string> 4 #include <functional> 5 6 namespace TransactionbyWLS 7 { 8 class CTaskItemBase 9 { 10 public: 11 virtual bool Doing()=0; 12 virtual bool Undoing()=0; 13 }; 14 15 static const int ENUM_BALENCEPOINT=1000; 16 static const int ENUM_BOUNDARYRANGE=500; 17 static const int ENUM_UPPERBOUNDARY=ENUM_BALENCEPOINT+ENUM_BOUNDARYRANGE; 18 static const int ENUM_LOWERBOUNDARY=ENUM_BALENCEPOINT-ENUM_BOUNDARYRANGE; 19 static const int ENUM_DELTA=1; 20 static const int ENUM_TRUE=1; 21 static const int ENUM_FALSE=0; 22 enum ETransRes { 23 EFALSE=ENUM_FALSE, 24 ETRUE=ENUM_TRUE, 25 26 ECOMMITSUCCESS=ENUM_BALENCEPOINT+ENUM_DELTA, 27 EDUMMY=ENUM_BALENCEPOINT,//1000,dummy. 28 ECOMMITFAILED_ROLLBACKSUCCESS=ENUM_BALENCEPOINT-ENUM_DELTA, 29 ECOMMITFAILED_ROLLBACKFAILED=ENUM_BALENCEPOINT-ENUM_DELTA*2, 30 }; 31 32 class CTaskBase 33 { 34 public: 35 typedef std::function<bool ()> TaskCALLBACK; 36 TaskCALLBACK m_TaskCallbackToDo; 37 TaskCALLBACK m_TaskCallbackToUndo; 38 39 CTaskBase():m_TaskCallbackToDo(0),m_TaskCallbackToUndo(0){} 40 41 virtual void SetToDo(TaskCALLBACK tcbDo) 42 { 43 m_TaskCallbackToDo=tcbDo; 44 } 45 46 virtual void SetToUndo(TaskCALLBACK tcbToUndo) 47 { 48 m_TaskCallbackToUndo=tcbToUndo; 49 } 50 51 virtual bool Do() 52 { 53 if (m_TaskCallbackToDo) 54 { 55 return m_TaskCallbackToDo(); 56 } 57 58 DummyDo(); 59 60 return true; 61 } 62 63 virtual bool Undo() 64 { 65 if (m_TaskCallbackToUndo) 66 { 67 return m_TaskCallbackToUndo(); 68 } 69 70 DummyUnDo(); 71 72 return true; 73 } 74 75 protected: 76 bool DummyDo() 77 { 78 std::cerr<<"DummyDo"<<std::endl; 79 80 return true; 81 } 82 83 bool DummyUnDo() 84 { 85 std::cerr<<"DummyDo"<<std::endl; 86 87 return true; 88 } 89 }; 90 91 typedef CTaskBase CTransactionTask; 92 typedef CTaskBase* CTransactionTaskPtr; 93 94 class CTransactionBase:public CTaskBase 95 { 96 public: 97 virtual bool AddTask(CTransactionTask*){std::cerr << "CTransactionBase:AddTask did noting."<<std::endl;return false