代码重构总结(上篇)

重构手法千变万化,如果你看过《重构_改善既有代码的设计》这本书一定会很有感触,此文我从这本书中挑选个人觉得比较有用的几点,一些我在工作中觉得比较实用的重构手法。

 

(01) - 方法提炼

有句话叫,当你为了给一段代码写注释的时候,你就能考虑把他提炼一下了。  
来看一个实际例子,登录  
配合idea的Refactor->Extract->Method  


原始代码如下:
01. public String login()
02. {
03. //错误信息
04. String error = "";
05. //1 显示验证码框
06. flag = "1";
07. //2 检查用户名密码为空
08. returnInfoBean = new ReturnInfoBean();
09. if (StringUtils.isBlank(custId))
10. {
11. error = "用户名不能为空";
12. }
13. else if (StringUtils.isBlank(custPassword))
14. {
15. error = "登录密码不能为空";
16. }
17. if(StringUtils.isNotBlank(error))
18. {
19. returnInfoBean.setSuccess(false);
20. returnInfoBean.setReturnMessage(error);
21. return "login";
22. }
23.  
24. try
25. {
26. //3 调用恒生登录
27. HsDsApi hsApi = new HsDsApi(";P            003", "integrate/login", LOGGER);
28. hsApi.put("logtype", logtype);
29. hsApi.put("lognumber", custId);
30. hsApi.put("password", custPassword);
31. if (StringUtils.isNotBlank(certificateType)) hsApi.put("certificatetype", certificateType);
32. HsResponse respx = hsApi.callHsApi();
33. returnInfoBean.setSuccess(respx.isSuccess());
34. if (respx.isSuccess())
35. {
36. //3.1 保存用户基本信息存入session
37. String sessionKey = respx.getString("sessionkey");
38. ICTLoginBean lb = new CTLoginBeanImpl();
39. lb.setUserInfo(getUserInfo(sessionKey));
40. lb.setAccountUtil(getAccountUtil(sessionKey));
41. request.getSession().setAttribute(ICTLoginBean.sessionID, lb);
42. }
43. else
44. {
45. //3.2 登陆失败返回错误代码并处理
46. throw new RuntimeException("【" + respx.getCode() + "】" + respx.getMessage());
47. }
48. } catch (Exception r)
49. {
50. //3.3 调用失败
51. error = "系统异常,请稍候再试";
52. LOGGER.error("调用恒生登录失败", r);
53. }
54.  
55. //4 是否登陆成功
56. if (StringUtils.isNotBlank(error))
57. {
58. returnInfoBean.setSuccess(false);
59. returnInfoBean.setReturnMessage(error);
60. return "login";
61. }
62. else
63. {
64. return "first";
65. }
66. }
其中2和3.1提炼到了private方法, 3提炼到了别的类里,因为明显这是个公共方法  
01. public String login()
02. {
03. returnInfoBean = new ReturnInfoBean();
04. returnInfoBean.setSuccess(true);
05. //1 显示验证码框
06. flag = "1";
07.  
08. //2 检查用户名密码为空
09. if (!checkLogin()) return "login";
10.  
11. try
12. {
13. //3 调用恒生登录
14. HsResponse respx = HsCommonAPi.login(logtype, custId, custPassword, certificateType);
15. if (respx.isSuccess())
16. {
17. //3.1 保存用户基本信息存入session
18. saveInfoToSession(respx.getString("sessionkey"));
19. }
20. else
21. {
22. //3.2 登陆失败返回错误代码并处理
23. throw new RuntimeException("【" + respx.getCode() + "】" + respx.getMessage());
24. }
25. }
26. catch (Exception r)
27. {
28. //3.3 调用失败
29. returnInfoBean.setSuccess(false);
30. returnInfoBean.setReturnMessage("系统异常,请稍候再试");
31. LOGGER.error("调用恒生登录失败", r);
32. }
33.  
34. //4 是否登陆成功
35. return returnInfoBean.isSuccess()?"first":"login";
36. }

 

(02) - 分解临时变量

一个变量变用在多个地方,而且每次使用含义都不同,这个时候可以考虑把他分解  


 

重构后  

 

(03) - 以查询取代临时变量

如果一个临时变量在方法里赋值有点复杂,而且可能还会被复用。可以提炼到方法里可以说是第1话的子范例  


 
重构后  


 
 

(04) - 引入解释性变量

不解释自己看例子,目的为了代码有更好地可读性 


重构后 


 
 

(05) - 使代码更简洁

这部分功能,欢迎大家投稿
1. if  ( flag ==  1  ){
2. return  true ;
3. }
4. else {
5. return  false ;
6. }
重构后
1. return  flag ==  1 ;

(06) - 尽早结束非正常逻辑

1. if(taskList != null && !taskList.isEmpty()){
2.  
3. //正常逻辑代码
4.  
5. return count;
6. }
重构后
1. int count = 0;
2. if(taskList == null || taskList.isEmpty()){
3. return 0;
4. }
5.  
6. //正常逻辑代码
7.  
8. return count;
除了return,抛出异常也是种结束方式
 

(07) - 满足条件立刻跳出循环

01. public boolean contain(int year, Month month, int day) {
02. boolean found = false;
03. for (IPolyDate date : dateList) {
04. if (date.same(year, month.getMonth(), day)) {
05. found = true;
06. break;
07. }
08. }
09.  
10. return found;
11. }
重构后
01. public boolean contain(int year, Month month, int day) {
02. for (IPolyDate date : dateList) {
03. if (date.same(year, month.getMonth(), day)) {
04. return true;
05. }
06. }
07.  
08. return false;
09. }
不但代码简洁还能提高效率
 

(08) - 使用数据构分离公共逻辑,避免重复(坚持DRY原则)

DRY原则: 不要重复粘帖你自己的代码。Don't repeat yourself  

01. public void testGetIntPart() throws Exception {
02. assertEquals("0", digitTransform.getIntPart("0.01");
03. assertEquals("1", digitTransform.getIntPart("1.2");
04. assertEquals("1234", digitTransform.getIntPart("1234");
05. assertEquals("1", digitTransform.getIntPart("1.01");
06. assertEquals("0", digitTransform.getIntPart("0.01");
07. assertEquals("11111", digitTransform.getIntPart("11111");
08. assertEquals("1000", digitTransform.getIntPart("1000.11");
09. }

重构后 

01.  public void testGetIntPart() throws Exception {
02.   String[][] cases = new String[][] { { "0.01""0" }, { "1.2""1" },
03. "1234""1234" }, { "1.01""1" }, { "0""0" },
04. "11111""11111" }, { "1000.11""1000" } };
05.  
06.   for (int i = 0, len = cases.length; i < len; i++) {
07.    assertEquals(cases[1], digitTransform.getIntPart(cases[0]));
08.   }
09.  }


(09) - 公共逻辑提炼

01. public int getRemainMinutes(int hour, int minute) {
02. if (this.fromAfterEqual(hour, minute)) {
03. return (toHour * 60 + toMinute) - (fromHour * 60 + fromMinute);
04. else if (this.toAfterEqual(hour, minute)) {
05. return (toHour * 60 + toMinute) - (hour * 60 + minute);
06. }
07. else {
08. return 0//(toHour * 60 + toMinute) - (toHour * 60 + toMinute);
09. }
10. }
重构后
01. private int getMinutes(int startHour, int startMinute, int endHour,
02. int endMinute) {
03. int minutes = 0;
04. minutes = (endHour * 60 + endMinute) - (startHour * 60 + startMinute);
05.  
06. return minutes;
07. }
08.  
09. public int getRemainMinutes(int hour, int minute) {
10. int startHour = toHour;
11. int startMinute = toMinute;
12.  
13. if (this.fromAfterEqual(hour, minute)) {
14. startHour = fromHour;
15. startMinute = fromMinute;
16. else if (this.toAfterEqual(hour, minute)) {
17. startHour = hour;
18. startMinute = minute;
19. }
20.  
21. return this.getMinutes(startHour, startMinute, toHour, toMinute);
22. }
 

(10) - 何时需要何时创建

01. public static Date parseDate(String date) throws ;P arseException {
02. SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
03.  
04. if ((date == null) || (date.equals(""))) {
05. return null;
06. }
07. else {
08. try {
09. return formatter.parse(date);
10. catch (ParseException pe) {
11. throw new ;P arseException(pe.getMessage(), pe.getErrorOffset());
12. }
13. }
14. }
重构后
01. public static Date parseDate(String date) throws ;P arseException {
02. if ((date == null) || (date.equals(""))) {
03. return null;
04. }
05. else {
06. try {
07. SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
08. return formatter.parse(date);
09. catch (ParseException pe) {
10. throw new ;P arseException(pe.getMessage(), pe.getErrorOffset());
11. }
12. }
13. }
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值