放下鼠标,离开键盘

Put the Mouse Down and Step Away from the Keyboard

你肯定有过花几个小时研究某个懊恼的问题,但始终没有个明确的解决方案。然后用力跺脚或者去题贩卖机,结果在回来的路上,灵光乍现。

这种情况请起来熟悉吗?有没有想过为什么会这样?其实是因为你一直在写代码,你大脑负责逻辑的区域被激活了,而负责创造的部分被关闭了。它不可能联想任何事情,直到你停止逻辑区域。

有个真实案例:我正在清理某段遗存的代码,并让其跑到了“关注”的方法里。它是设计用来校验一个字符串是否包含以hh:mm:ss xx格式的时间,其中hh表示小时,mm表示分钟,ss表示秒钟,xx表示AM或PM。

这个方法用以下代码将(表示小时的)两个字符转化为一个数字,并校验其是否在合法范围:

1
2
3
4
5
6
try {
    Integer.parseInt(time.substring(0, 2)); 
} catch (Exception x) {
return false;
}
if (Integer.parseInt(time.substring(0, 2)) > 12) {
return false;
}

相同的代码出现了两次,而且测试分钟和秒钟也只是通过修改相应的字符偏移和上限。方法的最后是用来检查AM和PM的实现:

1
2
3
if (!time.substring(9, 11).equals("AM") & !time.substring(9, 11).equals("PM")) {
return false;
}

如果这些比较流出现失败,就返回false,否则返回true。

以上代码看起来冗长且难以理解,但别担心。我知道该怎么做——就是说我已经想到一些办法来简化它了。我重构了它,并编写了一个简单的单元测试来确保它正常工作。

完成后,我对结果感到满意。新的版本更容易读懂,而且只有之前一半大小,也更精确了,因为之前的代码仅测试了小时、分钟、秒钟的上限。

当第二天准备上班的时候,我的脑袋碰的一下:为什么不用正则表达式来校验这个字符串呢?敲了几分钟键盘后,我仅用了一行代码就实现了该功能。如下:

1
2
public static boolean validateTime(String time) {
    return time.matches("(0[1-9]|1[0-2]):[0-5][0-9]:[0-5][0-9] ([AP]M)"); 
}

这个故事的重点不用我用一行代码就替换了原本的30行代码。重点是直到我离开电脑之前,我都自认为第一次的尝试就是问题的最佳解决方案。

所以,下次你碰到让人恼火的问题时,帮自己个忙。一旦你理解了这个问题,就去做一些可以激活你大脑创造力区域的事情——勾勒出问题,听一些音乐,或者去散个步。有时为了解决问题,你可以做的最好的事情或许是,放下鼠标,离开键盘。

0%