一次还算成功的重构实例
帮朋友重构的,重构的原则:消除过多的变量,消除控制结构的嵌套
重构之前
1 protected void btnSubmit_Click(object sender, EventArgs e) 2 { 3 string content = this.txtContent.Value; 4 string phones = ""; 5 string[] arrphone = null; 6 7 int mobilenum = 0; //输入的号码个数 8 int insertcount = 0;//记录插入成功条数 9 int errorcount = 0;//记录错误信息条数 10 ClassMain cm = new ClassMain(); 11 12 string username ="sys"; 13 string sendChannel=""; 14 int priority =0; 15 string sendContent=content; 16 string mobile=""; 17 string code=""; 18 UserInfo userinfo = cm.getUserInfo("sys"); 19 if (userinfo == null) 20 { 21 WebUtility.Alert(this, "系统专用群发帐户不存在,请先开通帐户名为:sys的帐户!"); 22 return; 23 } 24 priority = userinfo.priority; 25 26 27 if (string.IsNullOrEmpty(content.Trim())) 28 { 29 WebUtility.Alert(this, "短信内容不可为空,请输入短信内容!"); 30 return; 31 32 } 33 34 if (!string.IsNullOrEmpty(this.txtPhone.Text.Trim())) 35 { 36 37 phones = this.txtPhone.Text.Replace(" ", ""); 38 arrphone = phones.Split(new string[] { ",", ",", ";", ";", "\r\n", "\n", "\t" }, System.StringSplitOptions.RemoveEmptyEntries); 39 40 if (arrphone !=null && arrphone.Length > 0) 41 { 42 43 for (int i = 0; i < arrphone.Length; i++) 44 { 45 mobile = arrphone[i]; 46 if (System.Text.RegularExpressions.Regex.IsMatch(mobile, "^[1][3458]\\d{9}$")) 47 { 48 mobilenum++; 49 50 switch (hodgepodge.telecomoperators(mobile)) 51 { 52 case 1: 53 sendChannel = userinfo.ydSendChannel; 54 break; 55 56 case 2: 57 sendChannel = userinfo.ltSendChannel; 58 break; 59 case 3: 60 sendChannel = userinfo.dxSendChannel; 61 break; 62 default: 63 sendChannel = userinfo.dxSendChannel; 64 break; 65 } 66 67 code = cm.getportNumber(sendChannel) + userinfo.serviceCode; 68 69 if (cm.Insert_sms_send_batch(username, sendChannel, priority, sendContent, mobile, code) > 0) 70 { 71 insertcount++; 72 } 73 74 } 75 else 76 { 77 errorcount++; 78 } 79 80 } 81 82 } 83 84 if (mobilenum > 0) 85 { 86 87 string AlertText = "共有" + mobilenum+ "个合法的手机号码,"; 88 if (insertcount > 0) 89 AlertText += "其中" + insertcount + "个手机号码提交成功!"; 90 91 if (errorcount > 0) 92 AlertText += errorcount + "个因格式不正确没有提交!"; 93 94 WebUtility.Alert(this, AlertText); 95 string stime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); 96 string remark = AlertText; 97 cm.addActionlog(u.username, u.usernamecn, stime, "群发", Request.UserHostAddress, remark); 98 99 100 } 101 else 102 { 103 WebUtility.Alert(this, "无合法的手机号码,发送提交不成功!"); 104 105 } 106 } 107 else 108 { 109 WebUtility.Alert(this, "手机号码不可为空,请输入手机号码!"); 110 return; 111 } 112 113 114 }
重构之后
1 bool isValidPhoneNumber(string mobile) 2 { 3 return System.Text.RegularExpressions.Regex.IsMatch(mobile, "^[1][3458]\\d{9}$"); 4 } 5 6 string[] getPhoneList(string txtPhoneList) 7 { 8 string phones = txtPhoneList.Replace(" ", ""); 9 return phones.Split(new string[] { ",", ",", ";", ";", "\r\n", "\n", "\t" }, System.StringSplitOptions.RemoveEmptyEntries); 10 } 11 12 string[] siftOutVaildPhone(string[] phoneList) 13 { 14 List<string> vaildList = new List<string>(); 15 foreach(string phone in phoneList) 16 { 17 if (isValidPhoneNumber(phone)) 18 { 19 vaildList.Add(phone); 20 } 21 } 22 return vaildList.ToArray(); 23 } 24 25 string getChanel(string mobile, UserInfo userinfo) 26 { 27 switch (hodgepodge.telecomoperators(mobile)) 28 { 29 case 1: 30 return userinfo.ydSendChannel; 31 32 case 2: 33 return userinfo.ltSendChannel; 34 35 case 3: 36 return userinfo.dxSendChannel; 37 38 default: 39 return userinfo.dxSendChannel; 40 } 41 } 42 43 void PrintMessage(int mobilenum, int insertcount, int errorcount,ClassMain cm) 44 { 45 string AlertText = "共有" + mobilenum + "个合法的手机号码,"; 46 if (insertcount > 0) 47 AlertText += "其中" + insertcount + "个手机号码提交成功!"; 48 49 if (errorcount > 0) 50 AlertText += errorcount + "个因格式不正确没有提交!"; 51 52 WebUtility.Alert(this, AlertText); 53 string stime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); 54 string remark = AlertText; 55 cm.addActionlog(u.username, u.usernamecn, stime, "群发", Request.UserHostAddress, remark); 56 } 57 58 protected void btnSubmit_Click(object sender, EventArgs e) 59 { 60 string[] allPhoneList = null; 61 string[] vaildPhoneList = null; 62 int insertCount = 0;//记录插入成功条数 63 ClassMain dbHelper = new ClassMain(); 64 65 string username ="sys"; 66 UserInfo userinfo = dbHelper.getUserInfo(username); 67 if (userinfo == null) 68 { 69 WebUtility.Alert(this, "系统专用群发帐户不存在,请先开通帐户名为:sys的帐户!"); 70 return; 71 } 72 73 if (string.IsNullOrEmpty(this.txtContent.Value.Trim())) 74 { 75 WebUtility.Alert(this, "短信内容不可为空,请输入短信内容!"); 76 return; 77 } 78 79 if (string.IsNullOrEmpty(this.txtPhone.Text.Trim())) 80 { 81 WebUtility.Alert(this, "手机号码不可为空,请输入手机号码!"); 82 return; 83 } 84 85 //先取出整个点好号码列表,再筛选出来正确的号码 86 allPhoneList = getPhoneList(this.txtPhone.Text); 87 vaildPhoneList = siftOutVaildPhone(allPhoneList); 88 89 if (allPhoneList == null || allPhoneList.Length == 0) 90 { 91 WebUtility.Alert(this, "无合法的手机号码,发送提交不成功!"); 92 return; 93 } 94 95 96 //通过合法性检测以后的逻辑 97 for (int i = 0; i < vaildPhoneList.Length; i++) 98 { 99 string sendChannel = getChanel(vaildPhoneList[i], userinfo); 100 string code = dbHelper.getportNumber(sendChannel) + userinfo.serviceCode; 101 if (dbHelper.Insert_sms_send_batch(username, sendChannel, userinfo.priority, this.txtContent.Value, vaildPhoneList[i], code) > 0) 102 { 103 insertCount++; 104 } 105 } 106 107 PrintMessage(vaildPhoneList.Length, insertCount, allPhoneList.Length - vaildPhoneList.Length, dbHelper); 108 109 }
过程:
第一次完成基本功能(不包含错误的号码个数统计)整个过程只发生了两个编译错误(isValidPhoneNumber函数返回值定义成string而不是bool,PrintMessage函数定义成string而不是int)一个逻辑错误忘记调用isValidPhoneNumber验证正确的号码
第二次添加统计错误的号码有多少的功能,把getVaildPhoneList(该函数不存在了)分拆成getPhoneList和siftOutVaildPhone两个函数,一次通过编译和执行,0编译错误,0逻辑错误,还是能看出来,清晰正确的代码对于写出正确的代码有多重要!
bug:
重构过之后的29行有一个逻辑bug,他应该检测的是vaildPhoneList结果而不是allPhoneList,因为代码原本的意图是如果没有合法的号码,我就不向下执行了,如果检测总的号码列表,当全部都是坏号码时也能继续执行,但是这个问题是怎么产生的呢?我还能回忆出上次重构的过程,产生的原因是:进行第二次重构时,我只有一个电话号码列表,叫phoneList,重构前的代码是判断列表是不是空的,是空的不让向下执行,我重构的第一步是吧phoneList重命名成allPhoneList(使用VS的重构功能,相关的引用都自己改变了,结果if里的名字被自动该成了allPhoneList)之后添加vaildPhoneList,就忘了修改89行的条件。。。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述
2012-03-30 转:解决测试之疼<特别是单元、集成测试之疼>