一次代碼重構記錄

先說前言:ide

最近在作一個預警的功能。其中包含兩個表,一個預警主表,一個該預警對應崗位的子表,這兩個表是一對多的關係。優化

如今要作的這個功能是要新增一個預警。ui

新增預警時,要對主表插入一條記錄,對子表插入多條記錄。主表的主鍵是預警GUID,子表是雙主鍵,預警GUID+崗位GUID。this

好,那麼進入正題,這個功能實現起來不難。 第一次寫完以後,我把對這兩個表的數據插入和簡單的校驗都放在一個方法中。spa

其中,我以爲子表的數據集合的實體類生成方法,即預警崗位的實體類集合,能夠寫入一個方法裏,就將其抽離成一個方法。code

第一次實現的代碼以下所示:blog

 1 public void WarningPenetrateLowcostTotalPrice(CTSalesOrder so, CTCompanyConfig cc, CVRoom room)
 2 {
 3     // 沒有設置預警崗位時,不發送預警
 4     if (cc == null
 5         || cc.LowcostWarningStationIDList == null
 6         || cc.LowcostWarningStationIDList.Length == 0)
 7     {
 8         return;
 9     }
10 
11     var lowcostWarningStationIDList = cc.LowcostWarningStationIDList ?? "";
12     var plaView = new CTPenetrateLowcostWarningView();
13     var plasView = new CTPenetrateLowcostWarningStationView();
14     var lowcostWarningStations = lowcostWarningStationIDList.Split(',');
15     var newPenetrateLowcostWarningGUID = Guid.NewGuid();
16     var isSuccess = true;
17 
18     var pla = new CTPenetrateLowcostWarning();
19     var plasList = 
20         plasView.BuildArray(newPenetrateLowcostWarningGUID, lowcostWarningStations);
21 
22     if (plasList == null || plasList.Count == 0)
23     {
24         return;
25     }
26                 
27     pla.PenetrateLowcostWarningGUID = newPenetrateLowcostWarningGUID;
28     pla.SourceGUID = so.SalesOrderGUID;
29     pla.SourceType = so.SalesOrderType == "S" ? "8" : "9";
30     pla.PenetrateTime = DateTime.Now;
31     pla.TotalPrice = so.SalesOrderTotalPrice;
32     pla.StandardTotalPrice = room.ForSaleTotalPrice;
33     pla.LowcostTotalPrice = room.LowcostTotalPrice;
34     pla.OperatorID = so.LastEditAccountGUID.GetValueOrDefault() != CRMCommon.gNullGuid ?
35         so.LastEditAccountGUID.GetValueOrDefault() : so.AddAccountGUID;
36 
37     using (DbTransaction trans = plaView.BeginTransaction())
38     {
39         try
40         {
41             isSuccess = isSuccess && plaView.Insert(pla, trans);
42             foreach (CTPenetrateLowcostWarningStation plas in plasList)
43             {
44                 isSuccess = isSuccess && plasView.Insert(plas, trans);
45                 if (!isSuccess)
46                 {
47                     break;
48                 }
49             }
50 
51             if (isSuccess)
52             {
53                 isSuccess = isSuccess && plaView.CommitTransaction(trans);
54             }
55             else
56             {
57                 plaView.CloseTransaction(trans);
58             }
59         }
60         catch(Exception)
61         {
62             plaView.CloseTransaction(trans);
63         }
64     }
65 }
第一次實現

其中抽離出的方法爲:string

 1 public class CTPenetrateLowcostWarningStationView : IDDBOperator<CTPenetrateLowcostWarningStation>
 2     {
 3         /// <summary>
 4         /// 構建預警崗位實體類集合
 5         /// </summary>
 6         /// <param name="penetrateLowcostWarningGUID"></param>
 7         /// <param name="lowcostWarningStations"></param>
 8         /// <returns></returns>
 9         internal List<CTPenetrateLowcostWarningStation> BuildArray(Guid penetrateLowcostWarningGUID, string[] lowcostWarningStations)
10         {
11             if (lowcostWarningStations == null || lowcostWarningStations.Length == 0)
12             {
13                 return null;
14             }
15 
16             List<CTPenetrateLowcostWarningStation> plasList = new List<CTPenetrateLowcostWarningStation>();
17 
18             foreach (string stationGUID in lowcostWarningStations)
19             {
20                 plasList.Add(new CTPenetrateLowcostWarningStation()
21                 {
22                     PenetrateLowcostWarningGUID = penetrateLowcostWarningGUID,
23                     LowcostWarningStationGUID = CRMCommon.ToGUID(stationGUID),
24                     HasRead = "N"
25                 });
26             }
27 
28             return plasList;
29         }
30     }
BuildArray方法

--------------------------------------------------------------------------------------------------------------it

感受實現得還行,數數行數,65行,好像多了點。 我想了一下,發現主表的實體類的代碼也能抽出來作成一個方法,抽出來後的代碼爲:io

 1 public void WarningPenetrateLowcostTotalPrice(CTSalesOrder so, CTCompanyConfig cc, CVRoom room)
 2 {
 3     // 沒有設置預警崗位時,不發送預警
 4     if (cc == null
 5         || cc.LowcostWarningStationIDList == null
 6         || cc.LowcostWarningStationIDList.Length == 0)
 7     {
 8         return;
 9     }
10 
11     var lowcostWarningStationIDList = cc.LowcostWarningStationIDList ?? "";
12     var plaView = new CTPenetrateLowcostWarningView();
13     var plasView = new CTPenetrateLowcostWarningStationView();
14     var lowcostWarningStations = lowcostWarningStationIDList.Split(',');
15     var newPenetrateLowcostWarningGUID = Guid.NewGuid();
16     var isSuccess = true;
17 
18     var pla = plaView.BuildEntityBySalesOrder(so, room);
19     var plasList = plasView.BuildArray(newPenetrateLowcostWarningGUID, lowcostWarningStations);
20 
21     if (plasList == null || plasList.Count == 0)
22     {
23         return;
24     }
25 
26     using (DbTransaction trans = plaView.BeginTransaction())
27     {
28         try
29         {
30             isSuccess = isSuccess && plaView.Insert(pla, trans);
31             foreach (CTPenetrateLowcostWarningStation plas in plasList)
32             {
33                 isSuccess = isSuccess && plasView.Insert(plas, trans);
34                 if (!isSuccess)
35                 {
36                     break;
37                 }
38             }
39 
40             if (isSuccess)
41             {
42                 isSuccess = isSuccess && plaView.CommitTransaction(trans);
43             }
44             else
45             {
46                 plaView.CloseTransaction(trans);
47             }
48         }
49         catch(Exception)
50         {
51             plaView.CloseTransaction(trans);
52         }
53     }
54 }
第二次實現

此次抽離出的方法是plaView.BuildEntityBySalesOrder,代碼以下:

 1  /// <summary>
 2         /// 用銷售單實體類來構建預警實體類
 3         /// </summary>
 4         /// <param name="so"></param>
 5         /// <param name="room"></param>
 6         /// <returns></returns>
 7         internal CTPenetrateLowcostWarning BuildEntityBySalesOrder(CTSalesOrder so, CVRoom room)
 8         {
 9             if (so == null || room == null)
10             {
11                 return null;
12             }
13 
14             return new CTPenetrateLowcostWarning()
15             {
16                 PenetrateLowcostWarningGUID = Guid.NewGuid(),
17                 SourceGUID = so.SalesOrderGUID,
18                 SourceType = so.SalesOrderType == "S" ? "8" : "9",
19                 PenetrateTime = DateTime.Now,
20                 TotalPrice = so.SalesOrderTotalPrice,
21                 StandardTotalPrice = room.ForSaleTotalPrice,
22                 LowcostTotalPrice = room.LowcostTotalPrice,
23                 OperatorID = so.LastEditAccountGUID.GetValueOrDefault() != CRMCommon.gNullGuid ?
24                     so.LastEditAccountGUID.GetValueOrDefault() : so.AddAccountGUID,
25             };
26         }
BuildEntityBySalesOrder

--------------------------------------------------------------------------------------------------------------

好了,再數數行數,54行,只少了10行。這時我第一感受好像已經沒辦法再少了。 再看看代碼,發現佔了最多行數的是保存的動做。對了,保存也能弄成個方法,

而後我就再拆,拆成以下:

 1 public void WarningPenetrateLowcostTotalPrice(CTSalesOrder so, CTCompanyConfig cc, CVRoom room)
 2         {
 3             // 沒有設置預警崗位時,不發送預警
 4             if (cc == null
 5                 || cc.LowcostWarningStationIDList == null
 6                 || cc.LowcostWarningStationIDList.Length == 0)
 7             {
 8                 return;
 9             }
10 
11             var plaView = new CTPenetrateLowcostWarningView();
12             var plasView = new CTPenetrateLowcostWarningStationView();
13             
14             var lowcostWarningStationIDList = cc.LowcostWarningStationIDList ?? "";           
15             var lowcostWarningStations = lowcostWarningStationIDList.Split(',');
16             var pla = plaView.BuildEntityBySalesOrder(so, room);
17             var plasList = plasView.BuildArray(pla.PenetrateLowcostWarningGUID, lowcostWarningStations);
18 
19             plaView.AddWarning(pla, plasList);             
20         }
第三次視線

此次是將保存操做抽離成方法AddWarning,代碼以下:

 1 internal void AddWarning(CTPenetrateLowcostWarning warning, List<CTPenetrateLowcostWarningStation> warningStations)
 2         {
 3             if (warning == null || warningStations == null || warningStations.Count == 0)
 4             {
 5                 return;
 6             }
 7 
 8             var isSuccess = true;
 9             var plasView = new CTPenetrateLowcostWarningStationView();
10 
11             using (DbTransaction trans = this.BeginTransaction())
12             {
13                 try
14                 {
15                     isSuccess = isSuccess && this.Insert(warning, trans);
16                     foreach (var station in warningStations)
17                     {
18                         isSuccess = isSuccess && plasView.Insert(station, trans);
19                         if (!isSuccess)
20                         {
21                             break;
22                         }
23                     }
24 
25                     if (isSuccess)
26                     {
27                         isSuccess = isSuccess && this.CommitTransaction(trans);
28                     }
29                     else
30                     {
31                         this.CloseTransaction(trans);
32                     }
33                 }
34                 catch (Exception)
35                 {
36                     this.CloseTransaction(trans);
37                 }
38             }
39         }
AddWarning方法

--------------------------------------------------------------------------------------------------------------

在數數行數,主方法的行數已經降到19行。此次我總算是滿意了,也沒有再抽方法的衝動,好了,這個方法完工。

其中各抽出來的方法中,只有AddWarning方法要接近40行。其餘都是20左右。

 

總結一下,這個主方法從接近70行減小到19行。對這個結果我本身就不作什麼評論了。

 

歡迎你們回覆關於重構、優化、精簡代碼的建議。 對於個人重構,以爲不對的地方也歡迎指正。

相關文章
相關標籤/搜索