目录
1.前言
2.现象
3.如何写好代码
4.案例
第一例:
第二例:
第三例:
第四例:
5. 总结
本文论述内容,纯属个人见解,仅供参考。不做实际指导意见。
10+年工作经验中,有实际开发以及带队经验,经历过的系统及代码数不清了都,有自己年轻时被领导指导过的代码,有看过开源的代码,有读过其他同事的代码,有Review过队友的代码......
抛开实现不说,抛开对错不说,我们这次只关注代码的美观上。
看过这样的代码大家有没有经历过:
2.1 无注释,通篇干巴巴的代码-没有任何注释提示内容
2.2 代码一坨, 无任何层次感可言
2.3 重复代码,害怕改以前的代码,直接复制一份出来做自己的逻辑
2.4 大量IF/ELSE , if/else 太多,难以改动,改一次都惊心动魄,很难读懂
2.5 反人类思维,明明if(true)的事,非得用 if(!false)
2.6 疯狂的大括号{},代码逻辑流转不靠相应的return,throw Exception保证,直接括号 一括到底,各种括号嵌套。
2.7 流水账式代码- 不分段,不抽取,通体大段代码实现,-读完喘不过气来
2.8 补丁式代码- 本来一个小算法,小工具方法,可以提取到 工具类中,非得散落在各业务代码中,像一块块补丁,补在崭新的花衣上,怎一个丑字了得。
2.9 命名随意,胡乱翻译 , 风控 -翻译成 Wind Control - oh 。。。。
3.0 硬编码- 硬编码已经不合适了,还各种硬编码没解释, 代码中出现的 1,2,啥意思?头疼。。
等等....
先把代码的格式上搞好,再谈实现,代码让人读起来赏心悦目,清爽宜人。自己写的爽,别人看的爽。
3.1 得先见过什么样的代码是好代码,-井底之蛙认为天就那一块。多涉猎,广交流,多读源码,起码Spring 的源码应该搞定。
3.2 遵循一个原则:总-分 。 想想写作文时,我们要写个前言,写个目录之类的,所以任何代码段的核心逻辑是及其精炼的,列出 1.xxx 2. xxx 3.xxxx ,再针对 1.2.3 具体的子方法做相应的实现。
3.3 找到写代码的感觉-Sense。 沉浸式代码开发中,不以完成任务来写的代码,只是想把他写好,把那段代码当做一个艺术品去加工,反复雕琢,打磨,直至自己满意,一气呵成,岂不快哉!
下面引用一个实际的案例,看代码是如何一步步从杂乱走向了优雅。
案例引用自《大话重构》,
每次到一个新团队,总会和大家过一下这个案例,这个案例也一直影响了自己很多年的代码风格。
这是一个小算法,根据当前日期,计算出所在上午下午还是晚上,输出对应的打招呼内容
问题是:
1.没有注释
2.顺序编程
3.没有层次
4.变量命名不合理
5.常量抽取......
import java.util.Calendar;import java.util.Date;public class HelloWorld {public String sayHello(Date now, String user) {Calendar c;int h;String s = null;c = Calendar.getInstance();c.setTime(now);h = c.get(Calendar.HOUR_OF_DAY);if (h >= 6 && h < 12) {s = "Good Morning";} else if (h >= 12 && h < 19) {s = "Good afternoon";} else {s = "Good night";}s = "Hi," + user + ". " + s;return s;}}
进行了一些优化,可读性增强了些。
1.增加注释
2.调整顺序
3.重命名变量
4.进行分段
import java.util.Calendar;import java.util.Date;/*** 重构HelloWorld程序* @author JanhoSong**/public class HelloWorld {/*** 向大家问好* @param now* @param user* @return*/public String sayHello(Date now, String user) {//获得当前小时Calendar calendar = Calendar.getInstance();calendar.setTime(now);int hour = calendar.get(Calendar.HOUR_OF_DAY);//获取打招呼正确的语言String words = null;if (hour >= 6 && hour < 12) {words = "Good Morning";} else if (hour >= 12 && hour < 19) {words = "Good afternoon";} else {words = "Good night";}words = "Hi," + user + ". " + words;return words;}}
再次优化后抽取了可以提取的一些公共方法。
import java.util.Calendar;import java.util.Date;/*** 重构HelloWorld程序** @author JanhoSong**/public class HelloWorld {/*** 向大家问好** @param now* @param user* @return*/public String sayHello(Date now, String user) {int hour = this.getHour(now);return "Hi," + user + ". " + this.getGreeting(hour);}/*** 获取当前小时** @param now* @return*/private int getHour(Date now) {Calendar calendar = Calendar.getInstance();calendar.setTime(now);return calendar.get(Calendar.HOUR_OF_DAY);}/*** 获取打招呼内容** @param hour* @return*/private String getGreeting(int hour) {if (hour >= 6 && hour < 12) {return "Good Morning";} else if (hour >= 12 && hour < 19) {return "Good afternoon";} else {return "Good night";}}}
进一步提取,可以提取的工具类,抽取类出来。
import java.util.Calendar;import java.util.Date;/*** 日期工具类** @author JanhoSong**/public class DateUtil {/*** 获取当前小时** @param now* @return*/public static int getHour(Date now) {Calendar calendar = Calendar.getInstance();calendar.setTime(now);return calendar.get(Calendar.HOUR_OF_DAY);}}package com.longfor.org4;/*** 问候语类* * @author JanhoSong* */public class Greeting {/*** 获取前部分打招呼内容* * @param hour* @return*/public String getFirstGreeting(String user) {return "Hi, " + user + ". ";}/*** 获取后部分打招呼内容* * @param hour* @return*/public String getSecondGreeting(int hour) {if (hour >= 6 && hour < 12) {return "Good Morning";} else if (hour >= 12 && hour < 19) {return "Good afternoon";} else {return "Good night";}}}import java.util.Date;/*** 重构HelloWorld程序* * @author JanhoSong* */public class HelloWorld {/*** 向大家问好* * @param now* @param user* @return*/public String sayHello(Date now, String user) {int hour = DateUtil.getHour(now);Greeting gretting = new Greeting();return gretting.getFirstGreeting(user)+ gretting.getSecondGreeting(hour);}}
后续我们还可以再进行扩展,将每种打招呼的方法抽取成类,运用设计模式,这样就实现了可扩展,解除了IFelse。
写代码是一种享受,而写出的代码即一件艺术品,需要精雕细琢。