1. 程式人生 > >關於審批成功或確認逆向操作下有多個相同動作的程式設計

關於審批成功或確認逆向操作下有多個相同動作的程式設計

我們在開發過程中,一般都會遇到這樣的需求吧。審批通過的時候要執行多個動作:

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);
                }

至此,大功告成。如若後續業務需要增加扣款項,那麼我只需新建一個類,這個類實現了最初定義的介面,那麼我就必須去實現生成和退回操作,從而避免了漏操作的尷尬。

補充,如果我增加了一個業務,只需要在生成付款項的時候進行動作,刪除的時候不要有動作,那麼只要實現這個刪除動作,直接返回即可。