终于决定要写一些工作中的经验了,今天不忙,特意看了这几个月自己写的代码,然后分几个代码片段说说自己的理解以及给同行们参考。
之前看到最代码官方在网站中的一篇文章《关于公司WEB项目源码团队协作开发的一点想法》 看完后文中提到 “至于那些名词花哨的技术,身边牛逼哄哄的大牛,我们要学会视而不见,因为这些我们都终将学会,这些大牛我们终将超越。所谓大牛,无谓庖丁解牛,无它,惟手熟尔。” 我先不说他的对错,我只知道工作中前人(大牛)他们都有自己工作经验工作技巧,我想说的是我会看的见,然后去学习他们的技巧,这样不就是站在了巨人的肩膀上看远方了吗?
术业有专攻,闻道有先后。学习牛人的技巧、工作经验让自己尽快摆脱菜菜。不扯淡了,看下面几个片段。
片段一:不报错的代码,就对吗?
很多人开发的时候写代码,难免会觉得只要IDE没有报错就是对的,但是在程序运行的时候就会发现某某行报错了,于是又开始debug,经过一番调试后最后解决了这个问题。所以,我想问现有的代码没有报错的情况下,你的代码就真的没有问题吗?看看一下几句简单的代码片段:
public Response getStockInfo(@RequestParam Map<String, Object> params) { String code = (String) params.get( "code"); Long page = (Long) params.get( "page"); Long rows = (Long) params.get( "rows"); try { List<StockFuzzyDto> result = this.stockService .getStockByText(code,page,rows); return new Response(result); } catch (Exception e ) { log.info( e.getMessage()); // 封装异常信息 return ExceptionResponse(e ); } }
初看这段代码,感觉是没有什么问题,但是等代码运行起来的时候就会发现,在如下两行代码会报错
Long page = (Long) params.get( "page"); Long rows = (Long) params.get( "rows");
两个long 类型的变量 page 和 rows 从map里面get()出来然后强制转换为long类型。按照逻辑是对的,表面看起来也没有报错似乎没有错啊,哪里有问题呢。等程序运行的时候控制台就会告诉你
java.lang.ClassCastException : java.lang.String cannot be cast to java.lang.Long
分析:1,以上的问题很明显是说类型转化失败
2,强制转化有问题
解决方法:1,先判断非空再去进行一个类型的强制转化
在这里呢有的牛牛就会想到了,哦,先判断非空啊,然后就是对page rows 用if - else 判断不就完事了么,如下
if(page != null){ page = (Long) params.get( "page"); }
以上用了一个if 判断是可以做到判断非空的情况,这里我推荐大家用三元运算符,然后在用另外一种方式把page rows转化为long类型,将以上代码改为如下
Long page = params.get("page") == null?null :(long) Long.valueOf(params.get("page").toString()).intValue(); Long rows = params.get( "page") == null?null :(long) Long.valueOf(params.get("rows").toString()).intValue();
这里看起来是不是感觉简洁了很多,在整体感觉一下这个代码片段。
public Response getStockInfo(@RequestParam Map<String, Object> params) { String code = params.get( "code") == null ? null : (String) params.get( "code"); Long page = params.get("page") == null ? null :(long) Long.valueOf(params.get("page").toString()).intValue(); Long rows = params.get( "page") == null ? null :(long) Long.valueOf(params.get("rows").toString()).intValue(); try { List<StockFuzzyDto> result = this.stockService .getStockByText(code,page,rows); return new Response(result); } catch (Exception e ) { log.info( e.getMessage()); // 封装异常信息 return ExceptionResponse(e ); } }
这里的params是map类型,用get()得到值后toString()后变成string类型,然后用string 转化为long类型
小结:不是所有不报错的代码就是对的,用正确的逻辑去写代码,用简洁的方式去写代码,代码之美就在这些方面体现。
片段二:查看源码 用正确的 method()/interface 你也可以写出优秀的代码
先看如下代码:
public boolean preHandle(HttpServletRequest request, HttpServletResponse response , Object handler) throws Exception { Map<String, String> reqPara = new TreeMap<>(); Enumeration<String> names = request.getParameterNames(); while(names .hasMoreElements()){ String name = (String) names.nextElement(); reqPara.put( name, request.getParameter(name )); }
代码背景:这里原本是拦截器里面的一段代码,从request获取到一个个参数,然后放在map里面。这里有人问了,为什么要用TreeMap和Enumeration接口呢.
先一个一个的解释吧,为什么要用TreeMap ,而不是hashMap,因为我这里要对参数进行一个个的进行排序所以要选用的就是TreeMap,如果没有这个需求我们就可以改为hashMap,
因为hashMap要比treeMap 效率高。至于 treeMap 和 hashMap 的区别我这里就不展开解释了。
第二个怎么会采用Enumeration接口,
从 request.getParameterNames() 这里查看源码你会发现 getParameerNames()是 Enumeration 类型,如下:
public Enumeration getParameterNames();
具体查看 Enumeration
鼠标悬浮在Enumeration上然后 F2查看源码解释,不难得知,Enumeration的用法
对于Enumeration我也是无意间看见用到的,具体的大家可以去查询它的更多用法这里我也不展开说明了
小结:多看看源码,借鉴原理,你的代码也会很美
片段三:优化代码
如果你工作到了一定的年限,你回过头来看看自己写的代码,过了段时间你会发现原来,代码可以进行优化。对自己的代码优化,其实也是提升自己的能力
对于那些崇尚极简主义的程序员来说多的代码,就像自己身上的赘肉,非得要通过“减肥”的方式把“赘肉”去掉不可。这里就说说怎么给代码“减肥”
先看一段非常简单的代码
public JSONObject getChartsData(String gpdm ,String aniuid,String type ) { int level = 0;// 1VIP,0非VIP JSONObject response = new JSONObject(); if(null == aniuid ){ //游客 level = 0; } else{ // do some things } if(level == 1){ //VIP response.put( "code", 0); response.put( "msg", "" ); response.put( "success", true ); } else{ // !VIP // do some things response.put( "code", 0); response.put( "msg", "" ); response.put( "success", true ); } return response ; }
以上代码可以看出并没有什么问题,接下来就说说怎么给代码“减肥”,从代码结构来看,else 是可以删掉的,但不是把else里面的处理逻辑删掉,而是改变原来的结构
看如下减肥后的代码:
public JSONObject getChartsData(String gpdm ,String aniuid,String type ) { int level = 0;// 1VIP,0非VIP JSONObject response = new JSONObject(); if(null == aniuid ){ //游客 level = 0; } //do some things if(level == 1){ //VIP response.put( "code", 0); response.put( "msg", "" ); response.put( "success", true ); } // !VIP // do some things response.put( "code", 0); response.put( "msg", "" ); response.put( "success", true ); return response ; }
小结:从上可以看出,“减肥”后的代码更简洁,避免了冗余的else块,当然不是说所有的地方都非得要这么给代码“减肥”,具体情况具体分析。
对于代码优化,我还在探索的路上,这里写的几个片段只是我工作中的一小部分,希望大家看完了可以有所收获。
PS:我是 伊成 ,To Be A Better Man
(未完待续...)