记一次代码重构

前段时间,我负责一款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         }

现在想想,其实就是一个思路的问题,并没有什么难点,项目代码就不贴了,如果真有需要,留下个邮箱好了

时间: 2024-08-06 03:46:37

记一次代码重构的相关文章

记一次完整的系统业务代码重构(1)——why

记一次完整的系统业务代码重构(1)——why 0.为什么烂 优秀的代码优秀的出奇一致,烂代码却烂的千奇百怪.至于原因嘛,无非如下几种: 1.迭代和变更需求快,比翻书变脸还快,而且没有统一规划和为未来预留考虑. 2.公司人员流动快,代码换了一届又一届的主人,七朝元老都没站出来,三朝元老的代码都弱爆了. 3.神坑的技术人员,零注释.迷魂阵.障眼法没有最晕的代码只有更晕的代码. 1.烂在何处 让所有的开发人员吐槽自己维护的代码烂在何处,估计说个3天3夜都说不完.这里总结下自身项目的缺点.由于项目内容涉

代码重构实例之数据聚集

敏捷开发强调,要经常重构代码.在开发过程中,往往是开发和重构交替进行.短暂的重构,可以使得后续的开发维护更加容易.我觉得,代码重构可以分为逻辑重构和数据结构重构.数据结构的重构往往需要对代码进行多处改动:但是,数据结构的重构也可以为后续的开发维护带来更大的便利.这里就是一个数据结构重构的例子. 这是以前的一次代码重构经历,今天想起了,就记下来,帮助自己记忆.当然,既然是重构,总得承认自己写的第一版丑陋的代码. 为了方便描述,采用javascript来进行说明. 故事是这样的.刚开始,任务是画一些

NET代码重构

记一次.NET代码重构 好久没写代码了,终于好不容易接到了开发任务,一看时间还挺充足的,我就慢慢整吧,若是遇上赶进度,基本上直接是功能优先,完全不考虑设计.你可以认为我完全没有追求,当身后有鞭子使劲赶的时候,神马设计都是浮云,按时上线才是王道,毕竟领导是不会关注过程和代码质量的,领导只看结果,这也许就是我等天朝码农的悲哀. 需求:是这样的,要开发一个短信发送的模板,不同客户可能会使用不同的模板,而不同的客户使用的变量参数也是不同的.之前为了应急,线上已经完成了一个短信模板发送短信的功能,短信模板

Windows程序代码重构

代码重构:在程序功能实现之后,对代码进行一定规模的整理,使之符合"高内聚.低耦合"的软件设计原则,便于维护和使用. ①用函数封装消息处理代码--对Windows程序窗口函数中的每一个case程序段进行封装以形成一个消息处理函数,而在case中调用这个函数. ②利用数组或链表实现消息映射表进一步实现代码的隔离--因为窗口函数switch-case结构实质上实现的就是一个根据消息标识来查找消息处理代码的功能,故可以用消息映射表和一段查表程序来替代它,表中的每一项可以使用一个函数指针来指向消

Job Service代码重构遐想

最近有大概半个月的时间可以重构下代码,刚好可以重新整理下Job Service相关的代码.前段时间由于忙于完成Job Service所有功能以及完成对Auto Job的支持以正常上线,使得有些地方的代码写得不是特别优雅.主要集中在以下一些地方: DAG状态的转移 目前DAG状态分为3层,分别为ApplicationStatus.TaskStatus.InstanceStatus.每个层次都有以下几种状态,Waiting.Running.Finished.Stopped.Failed.并且DAG有

第九课、计算器界面代码重构

一.重构的概念 1.重构是以改善代码质量为目的代码重写 (1).使其软件的设计和架构更加合理 (2).提高软件的扩展性和维护性 2.代码实现和代码重构的不同 (1).代码实现:按照设计编程实现,重在实现功能 (2).代码重构:以提高代码质量为目的软件架构优化 (3).区别 A.代码实现时不考虑架构的好坏,只考虑功能的实现 B.代码重构时不影响已实现的功能,只考虑架构的改善 3.软件开发的过程 (1).从工程的角度对软件开发中的活动进行定义和管理 4.什么样的代码需要重构 (1).当发现项目中重复

step 1 代码重构

代码重构 代码重构介绍 重构目的 相同的代码最好只出现一次 主次方法 主方法 只包含实现完整逻辑的子方法 思维清楚,便于阅读 次方法 实现具体逻辑功能 测试通过后,后续几乎不用维护 重构的步骤 1  新建一个方法 ?                     新建方法 ?                     把要抽取的代码,直接复制到新方法中 ?                     根据需求调整参数 2  调整旧代码 ?                     注释原代码,给自己一个后悔的

转有关代码重构

转自:http://blog.csdn.net/weiky626/article/details/1602691 开发人员可能听到过"bad smell"这个词,这个词用在软件编码中是什么意思呢? 代码还有smell吗?当然没有,正如计算机病毒,bug等词一样,这只是个形象的说法.这个词在这里的意思是代码实现了需求,但是代码却不精炼,冗余,结构混乱,难读懂,难维护,难扩展等等.与之相对应的一个词是"refactor",即代码重构.我们在看些外国人写的程序时可以发现,

妮子的iOS 代码重构1

昨天面试,被问了个代码重构,直接愣住了... 回来稍微看了下,对代码重构有了一点了解...就是让自己的代码有更好的结构,更简洁易读吧,是提高代码质量的一种方法吧!Xcode提供了几个代码重构功能,有Rename(重命名).Extract.Create Superclass.Move Up.Move Down.Encapsulate. 使用:在代码区右击——Refactor,调出重构功能.Rename用于对类名.方法名.属性名等重命名,Extract用于将自己写的一段代码变成一个方法,Create