这是入门系列的第2篇,这1篇会继续上一篇的主题,来讨论一下日常写代码中,应当注意的地方,以及怎么写出高质量的代码,容易看懂,容易维护,稳定且不容易报错,容易二次开发的代码。还是想再次推荐一下Effective Java这本书,所以用这本书做了封面,并不是只需要看这1本书,作为程序员,会看很多本书,但是这本书,绝对是Java新手的首选,没有之一。
Math.min(int a, int b)方法的必要性
Math.min(a,b)方法,会返回a和b之中的较小的值。如果对java.lang.Math类中的这个方法不熟悉,也没有关系,这里并不想讨论方法的重载,也不想讨论怎么比较2个double类型或者2个float类型在获取最小值时候的不同(如果你是编程新手,建议你去学习下怎么比较2个double值),返回2个整型值中的较小的值,代码非常的简单,例如可以这么写:
int min(int a,int b) {
return a > b ? b : a;
}
那么,问题来了,我为什么要把这么简单的1个功能,做出来1个方法呢?干嘛要调用1个方法,而不是直接在调用Math.min(a,b)的方法,直接写这段逻辑呢?
int a = 10;
int b = 20;
int c = a > b ? b : a; // A
int d = Math.min(a,b); // B
对于A和B的不同的写法,有什么不同吗? 其实有很大的不同,这里先不考虑方法调用的开销,直观上来说,使用Math.min()让代码的可读性有了很大的提高,而且减少了出错的可能性,a,b两个变量的顺序,不影响最终的结果,Math.min(a,b)和Math.min(b,a)是等效的,但是对于A这种写法,就需要注意,是不是有可能会给写反了?
由此,我们可以延伸考虑,是什么时候需要把一段代码抽出来1个方法,什么时候不需要呢?先来考虑这么一种编程的场景:
int a = 10;
int b = 20;
// a == 10 && b == 20 表示业务情况A
if(a == 10 && b == 20) {
do something
} else {
do something
}
有一点要考虑的是是否有必要把条件修改为1个函数
boolean 业务情况A = a == 10 && b == 20
if(业务情况A) {
}
这样的代码,这其实和经常用的一个StringUtils.isBlank()或者CollectionUtils.isEmpty()有类似的地方,能用代码表示清楚意图的,尽量用代码表示,而不是写一段注释。所以可以时常考虑把一些代码的逻辑抽象出来,不一定要抽象成1个方法,也可以用1个变量来表示。
你可以再思考下,有没有其它的什么办法,能够提高代码的可读性?
关于日志
刚开始学习写代码的时候,如果想追踪代码,可以使用debug模型运行代码,也可以把一些变量输出在控制台,查看一些关键变量的值,在正式工作之后,就不能再把一些关键信息输出到控制台了,毕竟服务器上的标准输出,是不能保留的,而且性能不佳,无法落地留存,Java的日志框架也挺多,主流的也不多,但是今天我们想聊的是怎么打日志,哪里要打日志,打哪些内容。
- 日志要把关键信息打出来,就像写小说一样,人物,时间,地点,剧情都要写清楚,一般来说不用管时间,日志会自带,就只剩下人物和地点和剧情了,什么业务,什么参数,结果是成功还是失败,都要打印出来。
// 良好的日志
log.info("sku:{} 发生了一笔业务,参数是:{} 结果是:{}",sku,参数,结果);
//不好的日志 很鸡肋,不能起到日志应该有的作用,反而影响了性能
log.info("sku 发生了一笔业务");
- 日志要有节制,不能随意打,关键业务打印日志,报错的地方打印日志
- 日志应该尽量短,不能太长
- 日志可以在某些条件下打印,采样打印,例如可以判断当前时间戳,如果可以被10整除,才打印日志,这样能减少日志的条数
- 打印日志的时候,主要空指针异常
合理的设计类,不要把所有代码都放到1个文件
之前工作的1家公司,要求每个Java类长度不超过500行,我觉的是一个非常好的约定,避免了1个类膨胀的特别大,每个类应该设计为只为某一件事服务,不能什么都做。 比较经典的MVC分层结构,是大家都在用的方法,这里我认为并没有一个规则,来约定必须要多大的类,才需要拆分,如果你认为有必要,可以把读取Excel和读取Txt的类,拆分成2个类; 也可以把常量单独拆分、计算公式单独拆分、检查参数、解析文件、读取数据库、外部接口交互、MQ等,都单独拆分出来。
一直到拆的不能拆为止,但是也不能拆的太碎了,如果拆的太碎了,一定要有1个胶水类,把代码组织起来,这个胶水类,可以不做任何其它事情,就是调用其它的方法。
需要注意的是,类最好只堆外暴露需要暴露的方法,而不是把所有的方法,都设置为public的可见级别。
接口也是,谨慎的设计接口,因为一旦开始使用某个接口方法,后续可能会很难去掉。关于接口设计这块,其实也可以单独拿出来,仔细的分析一下,接口的设计也需要相当的功力,不过作为入门的文章,这里就不再多说了,可以参考下List这个接口,设计了size()接口方法,也设计了isEmpty()接口方法,看起来有重复,实际上是很玄学的事情,代表了2个不同的意思,体现了接口和实现的不同,你可以设计一个实现,size()不是0,但是isEmpty()返回true,只要你愿意的话。
其它的一些事情
对于新手入门的文章,接下来打算说一下具体的Java入门需要学习的东西,想要把编程的基础扎实了,还是要从Java基础学起,那么什么是Java基础呢?有哪些需要学习的东西呢? 接下来会讨论一下。
全文完。
关注我的博客,获取更多Java编程知识: 双King的技术博客