实践中的重构08_集合判空时的可读性
代码的可读性应该还是着重强调的,毕竟,代码是给人读的。如
if(null==a)
这样的代码,看的出是从c惯用法继承下来,试着读一下,当null不为a,则如何如何。至少我读起来有点别扭。我还是喜欢这样的形式,当a不为null,则如何如何。
当然,更厉害的是经常看到如下的片段
if(list.size()==0)if(list.size()<1)
ok,size==0这个我还可以想的通为什么这么写,但是<1这种写法真的让人无语。
if(list.isEmpty())
这样当然更进一步。为什么呢,因为使用size是因为我们知道该类的内部实现,判断时涉及了类的实现,而isEmpty只是语义上判断一个列表是否为空,不涉及实现细节。
还有一种挺常见的,好的做法是集合类引用对象永远不用判null。
if(list!=null && !list.isEmpty()){ // do something. } 我们可以把对list的判null和判空抽出来,变成
if(!CollectionUtil.isEmpty(list)){ // do something. }更进一步。
if(CollectionUtil.isNotEmpty(list)){ // do something. } 问题在于,null和empty在特定的上下文中真的是一样的吗。
private List<User> getUserList2(int size) {List<User> userList = new ArrayList<User>();userList.addAll(getUserListFromSource1(size - userList.size()));if (userList.size() >= size) return userList;userList.addAll(getUserListFromSource2(size - userList.size()));if (userList.size() >= size) return userList;userList.addAll(getUserListFromSource3(size - userList.size()));return userList;}
而且这代码还有改进的余地。但是没有上下文(对getUserList的调用;还有getUserListFromSourcex的定义),我只能写成这样。定义 类:节点服务器 定义 方法: 启动节点服务器 方法实现: 加载配置文件() IPQAM开始广播() 连接上分发服务器() 开始监听客户端连接和请求() 每5秒检查并清除一次死掉的终端连接() 记录系统启动日志()
然后会发现隐藏在更低一层的需求,发现需要定义加载配置文件,应该由一个专门配置系统的类来做:
定义 类:配置 定义 方法: 加载 方法实现: xxxxxxxx ......
然后是IPQAM的广播:
定义 类:IPQAM 定义 方法: 广播 方法实现: 遍历所有频道 频道.发送广播() 遍历结束
然后又发现隐藏在IPQAM中的更底层的需求,需要定义一个频道要处理频道自身的逻辑:
定义 类:频道 定义 方法: 发送广播 方法实现: UDPSocket.new.connect(ip, port).send('boradcast message', 0)只要把以上人类语言翻译成相应的代码即可。private List<User> getUserList2(int size) {List<User> userList = new ArrayList<User>();userList.addAll(getUserListFromSource1(size - userList.size()));if (userList.size() >= size) return userList;userList.addAll(getUserListFromSource2(size - userList.size()));if (userList.size() >= size) return userList;userList.addAll(getUserListFromSource3(size - userList.size()));return userList;}
而且这代码还有改进的余地。但是没有上下文(对getUserList的调用;还有getUserListFromSourcex的定义),我只能写成这样。
我是完全同意集合为空的情况下不返回null而是返回一个空集合这个惯例的。
但是有以下两种情况会有纠结的地方。
1 底层代码无法改动,加入一个间接层会提高别的程序员的使用成本。
2 大型项目中,一个人所能改动的代码是有范围限制的,对于自己没有改动权限的代码问题,最多提提建议。所以这个重构也只能局限在自己的系统中。
if(null==a)
这样的代码,至少我读起来有点别扭。
当然,更厉害的是
if(list.size()<1)
我知道有些人喜欢写成
if(list.size()==0)
ok,这个我还可以想的通为什么这么写,但是<1这种写法真的让人无语。
if(list.isEmpty())
这样当然更进一步。
毕竟,代码是给人读的。
好吧,其实一般都是这么用的
if(list!=null && !list.isEmpty()){//xixihaha}我们可以把对list的判null和判空抽出来,变成
if(!CollectionUtil.isEmpty(list)){//xixihaha}问题在于,null和empty在特定的上下文中真的是一样的吗。
list.size()==0 没有什么可读性差的。只是个人风格地问题。
为什么不这么写呢?
if(CollectionUtil.isNotEmpty(list))
if(null==a)
这样的代码,至少我读起来有点别扭。
当然,更厉害的是
if(list.size()<1)
我知道有些人喜欢写成
if(list.size()==0)
ok,这个我还可以想的通为什么这么写,但是<1这种写法真的让人无语。
if(list.isEmpty())
这样当然更进一步。
毕竟,代码是给人读的。
好吧,其实一般都是这么用的
if(list!=null && !list.isEmpty()){//xixihaha}我们可以把对list的判null和判空抽出来,变成
if(!CollectionUtil.isEmpty(list)){//xixihaha}问题在于,null和empty在特定的上下文中真的是一样的吗。
list.size()==0 没有什么可读性差的。只是个人风格地问题。
为什么不这么写呢?
if(CollectionUtil.isNotEmpty(list))
这样写的可读性更好。
问题在于,null和empty在特定的上下文中真的是一样的吗。
if(null==a)
这样的代码,至少我读起来有点别扭。
当然,更厉害的是
if(list.size()<1)
我知道有些人喜欢写成
if(list.size()==0)
ok,这个我还可以想的通为什么这么写,但是<1这种写法真的让人无语。
if(list.isEmpty())
这样当然更进一步。
毕竟,代码是给人读的。
好吧,其实一般都是这么用的
if(list!=null && !list.isEmpty()){//xixihaha}我们可以把对list的判null和判空抽出来,变成
if(!CollectionUtil.isEmpty(list)){//xixihaha}问题在于,null和empty在特定的上下文中真的是一样的吗。
list.size()==0 没有什么可读性差的。只是个人风格地问题。
为什么不这么写呢?
if(CollectionUtil.isNotEmpty(list))
这样写的可读性更好。
问题在于,null和empty在特定的上下文中真的是一样的吗。
不能完全肯定和否定,很多业务需要区分null和empty的!
一般null通过断言判断,在参数传递时,但是CollectionUtil类为了容错性,必须判断null到做empty!