几年前,我有机会负责一个项目咨询。团队很小,目标是用Java重写旧系统的后台,团队的开发人员都是C程序员。我的工作职责是负责项目设计和开发,并在项目开发过程中担任敏捷教练,培训Java开发人员。我在团队工作室的一角开了一家小诊所,大肆宣传——“一日一贴,百病通”。这是我当时对该项目的第二次诊断。1、变量的声明尽量和使用放在一起。这个规则关系到代码的可读性。如果方法没有保持简短,这个问题就更严重了。或许这是C语言开发者容易犯的错误。当然,很多Java程序员都从他们的前辈那里继承了这个坏习惯。我曾经在一个遗留项目中看到一个Java方法有几千行。几十个变量定义堆在方法的头部,看得头晕目眩!除了影响代码的可读性之外,还可能造成隐患。很多程序员之所以习惯一开始就声明变量,是因为他们把这个局部变量当做一个存放中间状态的容器,在方法内部反复使用这个变量。这个中间结果的变化可能不符合开发者的意图,或者后来代码的代码维护者没有对这个变化进行梳理,从而对变量值进行了误判。2.常量和枚举的使用在这条规则中无足轻重,写在这里是为了进一步警醒团队成员。在咨询过程中,看到了这段代码:Integer.parseInt(freeFlash,16);这个16是什么鬼?MagicNumber,经常让人摸不着头脑。在JDK提供枚举之前,很多Java程序员喜欢用接口类型来包装大量的常量。如果常量具有内聚的绝对意义,最好使用枚举。3、进行合理的封装是非常有必要的,避免对方法调用的错误封装。有时,暴露太多细节会使来电者感到不知所措。对于TelnetService类,我们需要依次调用connect()、login()、enterUShell(),然后exitUShell()和disconnect()必须在执行命令后依次执行。这让我想起事务处理、FTP访问等资源相关的逻辑,都需要在执行逻辑前后包裹一些基础设施处理逻辑。为了避免执行命令前后忘记连接或断开telnet,最好将这个过程封装起来。这是从通话安全的角度考虑的。如果考虑调用的简单性,封装也是必要的。当我们需要通过TelnetService发送telnet命令时,为什么需要了解内部执行逻辑呢?那么,如何封装两全其美,既满足执行逻辑序列的重用又满足命令逻辑的扩展呢?通常的做法是将真正的执行逻辑抽取出来作为接口,比如Java中Runnable的方式。这其实可以看做是Command模式的使用。当然,我更愿意把它看成是对函数的封装,比如Guva中的tranform()、filter()等方法,接受更具函数气质的Function或Predicate接口(Java8还没出来)。因此,我的做法如下:可以这样调用:Stringresult=telnetService.withCommand(newExecutionCommand
