文档结构  
可译网翻译有奖活动正在进行中,查看详情 现在前往 注册?
原作者:Michael Tofinetti (2016-10-03)    来源:Dzone [英文]
CY2    计算机    2016-10-09    1评/1571阅
翻译进度:已翻译   参与翻译: 薯片番茄 (12), toypipi (3), Orange (2), 城府很深 (1)

代码风格及其作用

编译器和解释器需要符合编程语言语法的正确语句,而人需要更多的信息来理解冰冷的机器指令。代码风格正好提供了这样的信息,它包括基本的文本格式、缩进以及短小的方法等。

风格同样适用于代表着最佳实践的设计模式,比如构建方法链、异常处理和同步等。具有良好风格的代码易于阅读,那感觉就像在阅读写得漂亮的散文一样。而易于阅读的代码意味着易于理解,意味着健壮,意味着更少错误,意味着开发者们的工作会更加愉快。

第 1 段(可获 1.48 积分)

代码风格也能使代码库中的代码更具一致性。然而,有时会存在好多年不具有良好风格的代码,这种情况下,最好不要急于修改代码,而应该考虑先改善其风格。改善代码不能急躁,最好从较新的文件开始。接下来修改文件中需要修改的部分,比如产生BUG的代码,而不要动其它的地方。一旦某个文件的修改量达到了某个程度(比如75%),剩下的不具良好风格的代码就更容易改善了。

第 2 段(可获 1.24 积分)

还有一点非常值得关注,现代集成开发环境(IDE)允许设置格式规则,这一点应该好好的利用起来。

现代Java代码风格的规则

简单,是代码风格最重要的一个方面,越简单的风格就越容易被记住和被应用。没有哪个开发者愿意去记忆上百条规则和数不清的特例。有一个总体指导原则,通常被称为“软件开发的童子军规则”。这就是说,开发者应该让代码不断的变得更好,就像童子军以他们的信仰保持着营地。

第 3 段(可获 1.43 积分)

编码和格式的亮点

代码格式

格式包括所有类型的约定,如基本外观、缩进、注释和括号应该放在哪里等。

一些最佳实践:

使用4个空格缩进代码。这即强调了文本的层次,又使得文本不会因为层次太多而被推得太远。使用空格进行缩进,不要使用制表符(Tab)。制表符不容易从空格中区分出来,但如果二者混用会引起一些麻烦,因为制表符的长度是由环境决定的。只使用空格就能保持一致的缩进长度。

第 4 段(可获 1.36 积分)

较长的代码行应该以80、120或132个字符为右边界,并在这之前折行。80 作为边界时,双边对比或多路合并会看起来更好,同时它也会造成更多的折行。

使用空格、空行和注释使代码更容易阅读。

大括号

大括号一直是各种代码风格讨论的焦点,不过总的来说只有两个主要的流派:后置和对齐。这两种方式都有自己的优缺点,下面会进行说明。

后置大括号方式将左括号放在语句的右边,最后一个位置,而反括号会独自一行。对于一些关联的关键字(如 “else”  和 “if”),会放在与反括号相同的行。

第 5 段(可获 1.45 积分)
if (condition) {
    statement;
} else {
    statement;
}

 

这种方式可以减少代码占用的垂直空间,一次在屏幕上显示更多的代码。然而,以这种方式压缩信息会降低可读性。括号对齐,或者,将括号直接放在彼此的上面。

if (condition)
{
    statement;
}
else
{
    statement;
}

 

这种风格通过引入空行使得语句被关键字环绕,由于每个大括号独占一行,瞬间提高了可读性。它还引入了大括号位置的一致性,因为他们总是在同一个地方,在引用语句正下方的第一个字符的位置。

第 6 段(可获 1.21 积分)

对齐的大括号使代码看起来更整齐划一,在一个括号里,由于语句过长导致折成多行时,这个优势尤其明显。

if (long condition with
    keyword and keyword and
    keyword and keyword)
{
    keyword;
}

如果采用后置的大括号风格,在上面示例的情况就需要在每个折行处多一层缩进,和括号内的执行语句区分开来。

在使用对齐的大括号风格时,格式化会自动对齐文本,使各项条件对齐,而不需要其它的格式规则或缩进。就这一点来说,我推荐对齐的大括号风格。

第 7 段(可获 1.14 积分)

命名规范

命名是编码的重要部分 — 挑选一个具表达意义的、对该结构有合适作用域和生命周期的适当名称。

一般来说,长的描述好过于简短的描述,但也要考虑到变量所存在的作用域。较小的作用域更适合采用短的名称, 而较长的名称更适合于生命周期更长的对象。

简短的,单字符适用于独立的循环语句中:

for (int i = 0; i < listSize; i++)
{
    if (condition)
    {
        sum += list.getItemAt(i);
    }
}
第 8 段(可获 0.96 积分)

作用域大的变量需要更长也更具表达能力的名字:

private CommandProcessor sequentialCommandProcessor =
    new CommandProcessor();

这个变量可能在类的各个地方都会用到,若调用的不同位置,可能不会同时在显示屏幕中展示。 .

sequentialCommandProcessor.init();
...
sequentialCommandProcessor.addCommand(...);
...
sequentialCommandProcessor.execute();
...
sequentialCommandProcessor.cleanUp();
...

一个具有表达能力的命名会减少花在推测变量意图的时间。上例中,长变量用驼峰大写连接单词,然而缩写时不要省略元音字母。首字母缩略词只有第一个字母需要大写,如parseXml()。

第 9 段(可获 1.06 积分)

为保持整个代码库的一致性,请采用一下命名规范

  • 类与接口名称的首字母大写。

  • 方法名及变量名称的首字母小写。

  • 常量全大写,单词之间用下划线连接,如: UPPERCASE_WITH_UNDERSCORES。

  • 包名用单个单词全小写。

编程设计中的亮点

规范

编程惯例涵盖了诸如类型安全、声明和表达式、链式构造函数、异常处理、断言、并发、异步以及效率等方面的实现。

第 10 段(可获 0.96 积分)

常见规范:

  • 即便语句块是空格或只有一行,也要用括号括起来; 如此可提高可阅读性,也可防止将来代码发生变化时出现问题。

  • 用括号表明执行顺序。

  • 用多态来减少switch语句的使用,同时,替换那些耗时且在循环中重复调用会引起性能问题的结构。

  • switch里面要总是放上default 的 case 语句,并且有break;而语句是在每个块的结尾,那么default也是。

第 11 段(可获 1.11 积分)

链式构造函数

构造对象是经常做的事情,而且通常会使用许多参数来简化构造. 在这种情况下,最好不要写重复的代码,而是使每个构造函数只做必要的最低工作, 将其余处理交给另一个构造函数.

public ChainedConstructor()
{
    // Common setup
    ...
}

public ChainedConstructor(ObjectTypeA a)
{
    ChaintedConstrucor();
    this.a = a;
}

public ChainedConstructor(ObjectTypeA a, ObjectTypeB b)
{
    ChainedConstructor(a);
    this.b = b;
}
第 12 段(可获 0.59 积分)

异常处理

开发者需要做的最重要的事情之一就是确保软件不会崩溃,即使是在意外场合也要做到这一点。在运行时,从无效用户输出到网络中断,任何问题都可能发生。正因如此,所有的潜在异常情况才必须被处理掉。

至少, 运行时异常应该被日志记录。要说异常情况从不发生,或者发生了但不造成影响,这种事情是非常罕见的。

try
{
    ...
}

catch (IOException e)
{
    // Should never reach here
    logger.debug(“Unexpected I/O exception:”);
    logger.logStackTrace(e);
}
第 13 段(可获 1.01 积分)

捕捉异常应该尽可能缩小异常的范围。不要在一个 try 块包装的范围内只捕捉 java.lang.Throwable 异常。一些异常比其他一些异常容易获取;最好不要把不可恢复的错误(如 java.lang.OutOfMemoryError)和可预期的异常(例如 java.lang.NumberFormatException 当把字符串转换成整形时)混在一起。

同步性

同步性保证在某个时刻只有一个线程可以访问一段特定代码或对象。在多线程环境下保证数据完整性有一个最重要的原则,为了达到同步的目的,应该分配并同步某个互斥对象。Java提供了一种机制将同步应用到类或方法,但这需要隐式或显式地使用类的实例对象本身作为同步对象。也就是说,对于类中所有同步的方法,只要线程锁定在其中某一个方法上,其它的方法就会被阻塞。 .

第 14 段(可获 2.14 积分)

因此, 为防止意想不到的事情发生, 我们会再使用一个Object对象,而不是用当前这个对象来做同步锁对象。

private String fileLock = “token”;
public void writeDataFile(String data)
{
    synchronized(fileLock)
    {
        dataFile.write(data);
    }
}

public String readDataFile(int lineNumber)
{
    String result;
    synchronized(fileLock)
    {
        result = dataFile.read(lineNumber);
    }
    return result;
}

同步操作具有排他性,这会造成代码块的运行速度降低。因此, 我们应该只对可能造成线程冲突或数据损坏的操作使用同步。

第 15 段(可获 0.63 积分)

结论

代码风格是软件开发的一个重要方面。明智且一致地应用一个良好定义的样式将使生成的代码更容易阅读,理解,和调试,以及更少的缺陷。

第 16 段(可获 0.4 积分)

文章评论

南京访客
这个{}一点都不java