關於審批成功或確認逆向操作下有多個相同動作的程式設計
阿新 • • 發佈:2018-12-17
我們在開發過程中,一般都會遇到這樣的需求吧。審批通過的時候要執行多個動作:
1.更改A表的狀態為“已審批”,我們記為操作A
2.插入B表一條資料 ,我們記為操作B
3.更改C表的多條資料的狀態,我們記為操作C
N多
.......
但是當N多天後,在業務發生需要逆向這個審批的時候,我們需要回滾這些操作。
我們需要一個不漏的逆向剛剛審批做的操作。
這個時候如果我們這樣寫:
審批方法() { 1.動作A 2.動作B 3.動作C ...... } 逆向方法() { 1.逆向A 2.逆向B 3.逆向C ...... }
這樣的話,如果後續業務再增加一個動作的時候,需要改動兩處地方,萬一漏掉一處(往往都是逆向處) ,並且測試都沒測出來,那麼問題就可大可小了。
我們從程式涉及上就可以避免這個問題的產生。
我這邊是生成付款清單*(情形類似)為例:
1.先定義一個介面,包含兩個方法:生成與刪除
public interface IPayToDealerOperate { /// <summary> /// 生成付款明細介面 /// </summary> /// <param name="db"></param> /// <param name="dbQuery"></param> /// <param name="listWarranty"></param>/// <param name="currentId"></param> /// <returns></returns> List<ClmPayToDealer> GeneratePayDetail(CEPEntities db, CepOneViewEntities dbQuery, List<ClmWarranty> listWarranty, long currentId); /// <summary> /// 刪除付款明細介面 /// </summary>/// <param name="DbContext"></param> /// <param name="dbQuery"></param> /// <param name="payMasterId"></param> /// <param name="currentId"></param> /// <param name="payDetailId"></param> /// <returns></returns> string DeletePayDetail(CEPEntities DbContext, List<ClmPayToDealer> payItemAllList, ClmPayToDealer pDetail, long currentId); }
2.為每個子動作分別建立類,並分別實現上面介面
public class PayNormalDetailImpl : IPayToDealerOperate { /// <summary> /// 生成付款明細介面 /// </summary> /// <param name="db"></param> /// <param name="dbQuery"></param> /// <param name="listWarranty"></param> /// <param name="currentId"></param> /// <returns></returns> public List<ClmPayToDealer> GeneratePayDetail(CEPEntities db, CepOneViewEntities dbQuery, List<ClmWarranty> listWarranty, long currentId) { //內含正常保修單生成付款項操作,此動作非重點已省略 return listPayToDealer; } /// <summary> /// 刪除付款明細介面 /// </summary> /// <param name="DbContext"></param> /// <param name="dbQuery"></param> /// <param name="payMasterId"></param> /// <param name="currentId"></param> /// <param name="payDetailId"></param> /// <returns></returns> public string DeletePayDetail(CEPEntities DbContext, List<ClmPayToDealer> payItemAllList, ClmPayToDealer pDetail, long currentId) { //內含收貨入庫刪除操作,此動作非重點已省略 return string.Empty; } }
public class PayPartReceiveInstockDetailImpl : IPayToDealerOperate { /// <summary> /// 生成付款明細介面 /// </summary> /// <param name="db"></param> /// <param name="dbQuery"></param> /// <param name="listWarranty"></param> /// <param name="currentId"></param> /// <returns></returns> public List<ClmPayToDealer> GeneratePayDetail(CEPEntities db, CepOneViewEntities dbQuery, List<ClmWarranty> listWarranty, long currentId) { //內含審計扣款生成付款項操作,此動作非重點已省略 return listPayToDealer; } /// <summary> /// 刪除付款明細介面 /// </summary> /// <param name="DbContext"></param> /// <param name="dbQuery"></param> /// <param name="payMasterId"></param> /// <param name="currentId"></param> /// <param name="payDetailId"></param> /// <returns></returns> public string DeletePayDetail(CEPEntities DbContext, List<ClmPayToDealer> payItemAllList, ClmPayToDealer pDetail, long currentId) { //內含收貨入庫刪除操作,此動作非重點已省略 return string.Empty; } }
public class PayAuditDebitImpl : IPayToDealerOperate { /// <summary> /// 生成付款明細介面 /// </summary> /// <param name="db"></param> /// <param name="dbQuery"></param> /// <param name="listWarranty"></param> /// <param name="currentId"></param> /// <returns></returns> public List<ClmPayToDealer> GeneratePayDetail(CEPEntities db, CepOneViewEntities dbQuery, List<ClmWarranty> listWarranty, long currentId) { //內含審計扣款生成付款項操作,此動作非重點已省略 return listPayToDealer; } /// <summary> /// 刪除付款明細介面 /// </summary> /// <param name="DbContext"></param> /// <param name="dbQuery"></param> /// <param name="payMasterId"></param> /// <param name="currentId"></param> /// <param name="payDetailId"></param> /// <returns></returns> public string DeletePayDetail(CEPEntities DbContext, List<ClmPayToDealer> payItemAllList, ClmPayToDealer pDetail, long currentId) { //內含審計刪除操作,此動作非重點已省略 return string.Empty; } }
3.在呼叫處定義介面陣列:
/// <summary> /// 付款清單新增資料與刪除資料,統一管理入口 /// </summary> private IPayToDealerOperate[] _payDetailOperateArray = new IPayToDealerOperate[] { new PayNormalDetailImpl(),//正常付款清單 new PayPartReceiveInstockDetailImpl(),//零件收貨入庫扣款 new PayAuditDebitImpl()//保修審計扣款 };
4.在呼叫處迴圈陣列執行相應動作。
4.1 在生成付款單處執行生成動作。
foreach (var action in _payDetailOperateArray) { listPayTotalItem.AddRange(action.GeneratePayDetail(db, dbQuery, item.ToList(), currentId)); }
4.2 在刪除付款單時執行刪除動作。
//迴圈處理_payDetailOperateArray中包含的還原扣款資訊 foreach (var action in _payDetailOperateArray) { action.DeletePayDetail(DbContext, payItemAllList, pdForDel, currentId); }
至此,大功告成。如若後續業務需要增加扣款項,那麼我只需新建一個類,這個類實現了最初定義的介面,那麼我就必須去實現生成和退回操作,從而避免了漏操作的尷尬。
補充,如果我增加了一個業務,只需要在生成付款項的時候進行動作,刪除的時候不要有動作,那麼只要實現這個刪除動作,直接返回即可。