一、从规约开始(Start from the Standard)
// Implementation of interface MyInterface
//---------------------------------------------------------------------进行分段。
5)、一定要有构造函数。
二、职责分配(Allocation of Responsibilities)
三、避免代码重复(Avoid Code Duplication)
重复的代码往往导致很多问题:
1)、太多代码。
2)、不容易看懂。
3)、不一致的实现。
4)、同一个东西需要修改多个地方。
四、避免字符常量(Avoid Literal Constants)
除了广为人知的几个:0、null、""以为,不应该在Java类中使用其他的字符常量。
if (balance > 10000) {
throw new SpendingLimitExceededException (balance, 10000);
}
字符常量往往导致:
1)、代码不能过自我描述。比如代码中的1000,你就不知道他是长度,还是大小。
2)、不容易看懂。
3)、同一个东西需要修改多个地方。
五、可见度和范围(Visibility and Scoping)
JdbcTemplate template = new JdbcTemplate(null);
template.update(new PreparedStatementCreator() {
public PreparedStatement createPreparedStatement
(Connection conn) throws SQLException {
PreparedStatement ps =
conn.prepareStatement("DELETE FROM TAB WHERE ID=?");
ps.setInt(1, 1);
return ps;
}
});
}
public void methodClass() {
JdbcTemplate template = new JdbcTemplate(dataSource);
class Counter implements RowCallbackHandler {
private int count = 0;
public void processRow(ResultSet rs) throws SQLException {
count++;
}
public int getCount() {
return count;
}
}
Counter counter = new Counter();
template.query("SELECT ID FROM MYTABLE", counter);
int count = counter.getCount();
}
六、使用final关键字
1、方法重载与final方法通常认为将一个方法设为final可能降低一个类的可重用性,因为它使得子类不能扩展这个方法。但是,实际上利用重载去扩展一个类是 不值得称道的。
建议将所有的public和protected的非虚方法设为final。这可以排除应为子类的错误重载而导致的bug。重载意味着潜在的危险。
“开闭原则”指出一个对象应该对扩展开放,对修改闭合。虽然通过重载一个具体类的方法,可以实现“用全新的代码,给一个程序添加新的功能,而不修改以前的代码”。但是,有更好的方法来扩展一个对象,而不是通过重载方法,比如:策略模式(Strategy design pattern)
为了方面以后的修改,针对可能需要扩展的方法,建议在方法的结尾调用一个专门添加的虚方法,以实现以后的扩展。这样既可以方面的扩展,有不会因为错误的扩展,而改变方法已有的功能。
public final void init() {如果,你重载一个方法的时候,需要完全颠覆这个方法的原有代码,只能说明类的继承体系出问题了。
// init helpers
//...
onInit();
}
protected abstract void onInit();
2、Final类
如果不需要对类进行任何修改,可以考虑将其设置为Final。
3、Final成员变量
一个final变量只能在声明时,后者构造函数中初始化一次。Final变量也是Java中唯一能够实现常量的方法。通常Final变量也可以将类自己的变量暴露在外而又避免修改。
七、现实toString()方法以方便诊断和Log
在toString()方法中实现描述对象的状态是一个很好的实践,也对Log有很多帮助。八、防御性的编程技巧
1、恰当的Nulls处理定义一个对象为null时的操作非常重要,建议遵循下列建议:
1)、记录下当方法接受到null时的行为。通常建议检查参数是否为null,记录下方法在null参数时的行为和什么时候抛出NullPointerExcetion非常重要,
2)、写出测试case去测试用null调用方法时的行为,是否和描述中的一样。
3)、不要假定一个方法永远不会是null。
2、考虑到比较对象时的次序
虽然下面两行代码正常时的表现一样,但是如果myStringVariable为null时,上面一句就会出错,而第二句会返回false。
if (myStringVariable.equals(MY_STRING_CONSTANT))3、使用短路赋值(Use Short-circuit Evaluation)
if (MY_STRING_CONSTANT.equals(myStringVariable))
我们可以利用Java的短路赋值,比如
if ( (o != null) && (o.getValue() < 0))
即使为o为null,也不会出现问题。当o为null时,第二条不会执行。
4、区分错误消息和消息的内容
消息”Error in com.foo.bar.MagicServlet: Cannot load class ‘com.foo.bar.Magic’“比”Error in com.foo.bar.MagicServlet: Cannot load class com.foo.bar.Magic“更详细的描述了错误的信息。
5、使用Arrays而不是Collections
Java中的使用Collections意味着必须进行类型转换,而类型转换的代码往往比较缓慢,复杂,容易出问题,所以应该尽可能使用类型化的Array。
九、文档
任何语言中不充分的文档都是不可原谅的。Java通过Javadoc为标准化的文档提供了条件。文档的目的:1)、提供对象和方法的契约。测试Case也是一中很好的说明。并且文档和测试Case应该保持同步。
2)、避免开发者在使用代码之前必须阅读它。没有必要去验证代码如何工作或是否操作。Javadoc确定作什么,测试Case确定代码作了文档中写的。
3)、解释非明显的实现。
建议使用的文档规范:
1)、学习如何使用Javadoc(比如@param,@throws)。可以查看对应版本JDK的Javadoc。
2)、为所有方法写Javadoc,包括私有方法。可以使用工具生成框架,然后自己填写其他的信息,特别注意方法如何处理null。
3)、永远记录方法运行时异常(runtime exceptions)。可以通过@throws声明。
4)、Javadoc说明类和方法 作了什么。可以使用//或者/*在内部注明 如何去做。
5)、使用/*注视超过3行的注释,使用//注释少点的。
6)、为所有成员变量写注释。
7)、不用为重复实现的接口的注释,只针对特定的实现写注释。使用@see标签指向接口的JavaJoc。
8)、永远注释出Map类型的键和值的类型。
9)、同样注释出Collection的类型。
10)、只为需要的代码添加注释。直到代码不能很好的说明自己时,才为他们添加注释。
11)、不要为显而易见的代码添加注释。
12)、利用任何机会去完善文档。
13)、在每个包中包含一个package.html。
14)、