程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 記一次代碼重構,代碼重構

記一次代碼重構,代碼重構

編輯:關於.NET

記一次代碼重構,代碼重構


      前段時間,我負責一款APP的接口開發,其中有一個新增的操作,邏輯比較復雜,涉及到9個數據表的數據改動,而且表又跨庫,這9個表呢,個別在別處還有單表操作,所以為了復用之前的數據層,筆者直接想到了使用分布式事務TransactionScope,在業務層直接調用多個DAO類的方法。

        再說下這個新增操作吧,這個APP是用來回收某產品的,所以這個新增操作是創建一個二手產品的訂單,首頁是五個項目,如圖(下圖中各具體項只是為說明數據結構),                   資料從左向右填寫,每次填完信息暫存在本地,點創建回收訂單,信息提交到後台接口,其中【產品信息】下的配置信息和【產品描述】【圖片信息】的全部信息采用配置字典表分別存儲,產品描述關聯到訂單,而配置信息和圖片則關聯到產品。全部本地信息以JSON格式提交,格式如下
{
    "data": {
  "customer": {
           
            "CustomerName": "Ikki裡",
            "Mobile": "13988888888",
 "Address": " "
        },
 "product": {
            "Name": "",
            "CPU": "",
            "Color": 0
        },
        "productCI": [
            "1,2",
            "2,1",
            "3,0"
 
        ],
        "productCheck": [
            "227,",
            "231,A+"
        ],
        "productPic": [
            {
                "ViewUrl": "http://imageup.xxxx.com/xxxxx/09/03/85b9213e-7bf3-4312-b59f-276ea0f9ac70_901.png",
                "ImgText": "左前",
                "PicPath": "/xxxx/09/03/85b9213e-7bf3-4312-b59f-276ea0f9ac70_{0}.png",
                "DictID": 349
            }
        ],
        "productPrice": {
            "PriceMax": "66.0",
            "PriceMin": "1.0",
            "Note": "abc",
        },
       
      
    }
}

 

       一切進行得還算順利,但當把程序部署到正式環境時,問題出現了,提示分布式事務未被初始化之類的錯誤,具體想不起來了,嘗試了網上的一些解決方法,比如本地DTC的一些設置,但都無效果,最後只好放棄了,又想到兩個解決方案,第一,在DAO層中重寫一個大的方法,包含全部的數據操作方法,在DAO類中DbTransaction 事務;第二,使用存儲過程,但想到要給存儲過程傳這麼多參數進去,我還是放棄了。好吧,就按第一種解決思路來。         重構的定義是在不改變系統的外部功能的前提下,只對內部的結構進行重新的整理,換到我現在的環境就是APP已經開發測試完成,所以我的接口的任何改變都不應該讓APP感覺到我的變化,接下來我做的事就是對現在的代碼重構,頓時覺得自己做一件很高大上的事,哈哈。        先說下之前的操作方法吧,代碼太多了,我就簡單示例下    
  private string Add(HttpContext context)
        {
            string result = string.Empty;
            using (System.Transactions.TransactionScope scope = new System.Transactions.TransactionScope())
            {
                #region 1、客戶資料
                CustomerDao.Add();
                     or  CustomerDao.Update  ();
                #endregion
                #region 2、產品信息,
                ProductDao.Add();
                     or  ProductDao.Update  ();
                #endregion                
                #region 4、圖片信息
                PicDao.Add();
                     or   PicDao.Update  ();
                #endregion
                #region  5、回收價格
                PriceDao.Add();
                     or PriceDao.Update  ();
                #endregion
                #region 3、產品描述信息
                ProductDesDao.Add();
                    or ProductDesDao.Update  ();
                #endregion
                scope.Complete();
                result = ERP.Common.Json.JsonHelper.ReturnJson(1, "保存成功!");
            }
            return result;
        }

        難道真的要把每個DAO下的方法復制粘貼出來,然後拼SQL,對參數?簡直難以想像,那樣還意味著以後要維護兩套DAO方法,並且是同一功能。關鍵是明天早上是必須要交付給客戶的,現在已經晚上快10點了...

        終於想到一個比較靠譜,又敏捷的方法,為了保險,我新建一個類,專門用來組織SQL和參數,把原來的DAO方法復制到這個類中,然後不執行SQL,而是用一個字典返回SQL+參數,這樣在上層調用接收到這個字典,用字典的原因是由於每個DAO方法的參數類型不同,這樣方便接收。把所有5個要執行的操作都接收完成後,再寫一個總的保存方法,這個方法裡可以用IDbTransaction事務來保證安全。原來的單個表操作的方法也可以直接用這樣的方式來調用保存,不受影響,最重要的是APP端不用做任務的改動。       總的保存方法如下: 1 public ResultModel SaveAll(Dictionary<string, object> dicParam) 2 { 3 ResultModel ret = new ResultModel(); 4 ret.Status = 0; 5 ret.Message = ""; 6 lock (padlock) 7 { 8 IDbTransaction trans = null; 9 try 10 { 11 using (var conn = new SqlConnection(DbConnString)) 12 { 13 conn.Open(); 14 trans = conn.BeginTransaction(); 15 Dictionary<string, object> _param = new Dictionary<string, object>(); 16 var sql = string.Empty; 17 var countSql = string.Empty; 18 var delSql = string.Empty; 19 //1、客戶資料 20 int sellerId = 0; 21 _param = (Dictionary<string, object>)dicParam["sellerCarInfo"]; 22 SellerCarInfoModel sellerModel = (SellerCarInfoModel)_param["model"]; 23 sql = _param["sql"].ToString(); 24 if (sellerModel.ID > 0) 25 { 26 conn.Execute(sql.ToString(), sellerModel, trans); 27 sellerId = sellerModel.ID; 28 } 29 else { 30 countSql = _param["countSql"].ToString(); 31 int cnt = conn.ExecuteScalar<int>(countSql, null, trans); 32 sellerModel.CustomerNo = string.Format("PC{0}{1}", DateTime.Now.ToString("yyMMdd"), (cnt + 1).ToString().PadLeft(4, '0')); 33 sellerId =conn.ExecuteScalar<int>(sql.ToString(), sellerModel, trans); 34 } 35 DebugLog("1、客戶資料", sql, sellerModel); 36 //2、車輛信息,不含車況 37 //1),基本信息,手續信息、圖片信息、配置信息 38 int carId = 0; 39 _param = (Dictionary<string, object>)dicParam["carBaseInfo"]; 40 CarBaseInfoModel carBaseInfoModel = (CarBaseInfoModel)_param["model"]; 41 sql = _param["sql"].ToString(); 42 if (carBaseInfoModel.ID > 0) 43 { 44 conn.Execute(sql.ToString(), carBaseInfoModel, trans); 45 carId = carBaseInfoModel.ID; 46 } 47 else 48 { 49 carId = conn.ExecuteScalar<int>(sql.ToString(), carBaseInfoModel, trans); 50 } 51 DebugLog("2、車輛基本信息,手續信息", sql, carBaseInfoModel); 52 //2)配置信息 53 _param = (Dictionary<string, object>)dicParam["carCi"]; 54 List<CarCIModel> listCi = (List<CarCIModel>)_param["list"]; 55 sql = _param["insertSql"].ToString(); 56 delSql= _param["delSql"].ToString(); 57 if (listCi.Count > 0) { 58 conn.ExecuteScalar(string.Format(delSql, carId),null,trans); 59 foreach (var item in listCi) 60 { 61 item.CarID = carId; 62 conn.ExecuteScalar(sql, item, trans); 63 } 64 } 65 //3)圖片信息 66 _param = (Dictionary<string, object>)dicParam["carPic"]; 67 List<AssessImageModel> listPic = (List<AssessImageModel>)_param["list"]; 68 sql = _param["insertSql"].ToString(); 69 delSql = _param["delSql"].ToString(); 70 if (listPic.Count > 0) 71 { 72 conn.ExecuteScalar(string.Format(delSql, carId), null, trans); 73 foreach (var item in listPic) 74 { 75 item.CarInfoID = carId; 76 conn.ExecuteScalar(sql, item, trans); 77 } 78 } 79 //3、 [PingguCarInfo] 車冗余表信息 80 int redundanceCarId = 0; 81 _param = (Dictionary<string, object>)dicParam["pingguCarInfo"]; 82 PingguCarInfo pingguCarInfo = (PingguCarInfo)_param["model"]; 83 sql = _param["sql"].ToString(); 84 if (pingguCarInfo.Id > 0) 85 { 86 conn.Execute(sql.ToString(), pingguCarInfo, trans); 87 redundanceCarId = pingguCarInfo.Id; 88 } 89 else 90 { 91 redundanceCarId = conn.ExecuteScalar<int>(sql.ToString(), pingguCarInfo, trans); 92 } 93 DebugLog("3、 [PingguCarInfo] 車冗余表信息", sql, pingguCarInfo); 94 //4、創建評估單 95 int pingguId = 0; 96 _param = (Dictionary<string, object>)dicParam["pingguOrder"]; 97 PingguOrderModel pingguOrder = (PingguOrderModel)_param["model"]; 98 pingguOrder.CarInfoId = carId; 99 pingguOrder.SellerId = sellerId; 100 pingguOrder.RedundanceCarId = redundanceCarId; 101 sql = _param["sql"].ToString(); 102 countSql = _param["countSql"].ToString(); 103 int _cnt = conn.ExecuteScalar<int>(countSql, null, trans); 104 pingguOrder.PingguNo = string.Format("A{0}{1}", DateTime.Now.ToString("yyyyMMdd"), (_cnt + 1).ToString().PadLeft(4, '0')); 105 pingguId =conn.ExecuteScalar<int>(sql.ToString(), pingguOrder, trans); 106 DebugLog("4、創建評估單", sql, pingguOrder); 107 //5、車況檢測信息 108 _param = (Dictionary<string, object>)dicParam["carCheck"]; 109 List<CarCheckItemsModel> listCheck = (List<CarCheckItemsModel>)_param["list"]; 110 sql = _param["insertSql"].ToString(); 111 delSql = _param["delSql"].ToString(); 112 if (listCheck.Count > 0) 113 { 114 conn.ExecuteScalar(string.Format(delSql, pingguId), null, trans); 115 foreach (var item in listCheck) 116 { 117 item.CarId = pingguId; 118 conn.ExecuteScalar(sql, item, trans); 119 } 120 } 121 122 //6、保存CarStoreAssociation關系 123 _param = (Dictionary<string, object>)dicParam["carStoreAss"]; 124 Model.CarManage.CarStoreAssociation carStore = (Model.CarManage.CarStoreAssociation)_param["model"]; 125 sql = _param["sql"].ToString(); 126 carStore.CarID = carId; 127 conn.ExecuteScalar(sql.ToString(), carStore, trans); 128 DebugLog("6、保存CarStoreAssociation關系", sql, carStore); 129 ret.Status = 1; 130 ret.Message = ""; 131 // throw new Exception(); 132 trans.Commit(); 133 } 134 } 135 catch (Exception ex) 136 { 137 ret.Status = 500; 138 ret.Message = ex.Message; 139 Log4NetHelper.Error("APP保存車輛信息時出錯:" + ex.Message, ex); 140 trans.Rollback(); 141 } 142 } 143 return ret; 144 } View Code

       現在想想,其實就是一個思路的問題,並沒有什麼難點,項目代碼就不貼了,如果真有需要,留下個郵箱好了

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved