代码规约

J2ee是针对大的项目的,大项目往往需要团队协作,而一致的编程风格是团队协作的保证。

一、从规约开始(Start from the Standard)

    编码规约要点:
        1)、给参数赋予有区别的、有意义的名字。比如对一个属性的赋值方法中的参数可以命名为:newProperty。
        2)、凡是使用了成员变量的地方,一定使用 this
        3)、成员变量名尽量详细,而局部变量名尽量简短。比如同样是SystemUserInfo的实例,成员变量应该命名为:systemUserInfo。而局部变量应该命名为:newUser。
    代码组织规约要点:
        1)、通过功能组织方法,而不是通过访问权限。
        2)、将代码分为不同的区域。比如实现了一个接口的方法可以使用
  //---------------------------------------------------------------------
  // Implementation of interface MyInterface
  //---------------------------------------------------------------------进行分段。
        3)、任何静态变量、静态方法、特别是main()方法,都不应该存在。UT测试,应该通过Junit进行。
        4)、把所有成员变量,放在一起。
        5)、一定要有构造函数。
        6)、通过类发布public方法,而不是通过实现的接口( ??)。
        7)、abstract方法应该是protected的。
        8)、protected的方法,的确是子类需要使用的。
        9)、实现的方法不要和任何之前实现的代码有关联。

二、职责分配(Allocation of Responsibilities)

 
    每一个类都应该有清晰的职责。不合适的代码应该被重构,通常都是放到helper类中,inner class有时也是一个好地方。一个helper类的继承体系通常比较好。
    即使包含Javadoc和注释,一个类也不应该超过500行。
    同样,对于方法也是这样的。每一个方法都应该有清晰的职责,并且所有操作都应该在同一个抽象等级上。方法的长度,应该在一个屏幕能显示开为好。不包括Javadoc应该在30-40行左右。

三、避免代码重复(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)

    成员变量和方法应该拥有最小的可见度。局部变量应该声明在真正使用的代码块中。
    1、公共的成员变量(Public Instance Variables)
        公共的成员变量往往时失败的设计或者懒惰程序员的反映。
    2、受保护的、包内的成员变量(Protected and Package Protected Instance Variables)
        禁止使用packag可见度。除非是常量,非则也不要用protected可见度。
        多有的成员变量,都应该是private的。
    3、方法的可见度
        应该尽量的小。
    4、变量的范围
        变量的声明应该尽量接近,变量使用的地方。
    5、内部类和接口(Inner Classes and Interfaces)
        内部类和接口能够帮助Java避免命名域污染。内部类通常用来帮助主类实现一致的职责。
        静态内部类和非静态内部类:静态内部类可以不通过主类的实例来访问。而非静态内部类就不可以。
        匿名内部类(Anonymous inner classes)不能促进代码的重用,没有构造函数,只能通过一个方法访问。所以不提倡使用。
  public void anonClass() {
    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))

if (MY_STRING_CONSTANT.equals(myStringVariable))
3、使用短路赋值(Use Short-circuit Evaluation)
    我们可以利用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)、
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值