先說前言: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 }
--------------------------------------------------------------------------------------------------------------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 }
--------------------------------------------------------------------------------------------------------------
好了,再數數行數,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 }
--------------------------------------------------------------------------------------------------------------
在數數行數,主方法的行數已經降到19行。此次我總算是滿意了,也沒有再抽方法的衝動,好了,這個方法完工。
其中各抽出來的方法中,只有AddWarning方法要接近40行。其餘都是20左右。
總結一下,這個主方法從接近70行減小到19行。對這個結果我本身就不作什麼評論了。
歡迎你們回覆關於重構、優化、精簡代碼的建議。 對於個人重構,以爲不對的地方也歡迎指正。