四年的开发了,经常觉得自己的代码不规范,没有自己的风格。今天先整理部分,以后更要积累,编码要严格遵循。
应用分层
1、 参照阿里巴巴规范
2、分层领域及命名规范
DO(Data Object):与数据库表结构一一对应,通过DAO层向上传输数据源对象。
DTO(Data Transfer Object):数据传输对象,Service和Manager向外传输的对象。
BO(Business Object):业务对象。可以由Service层输出的封装业务逻辑的对象。
QUERY:数据查询对象,各层接收上层的查询请求。超过2个参数的查询封装,禁止用Map类传输。
VO(View Object):显示层对象,通常是Web向模板渲染引擎层传输的对
3、保证底层方法的原子性。特别是上图中的DAO层和Manager层。
编码的通用原则
1、单一职责,最好能用一句话概括一个模块。
方法可复用,一个方法只做一件事,不要在方法参数中加boolean,不要过于追求方法的通用性。之前Manager层的一个查询方法我希望能满足大多需求,结果简单的逻辑复杂化了。方法的入参要干净,让使用者好调用,编码要清晰,好做优化。
类不要过于笨重,定义类的时候考虑类的功能。通常都是使用spring、mybatis、SpringMVC这些框架,从Controller到Dao,这些类都是无状态的。Dao和Manager可以与数据表或者领域对应,在往上可以从业务的角度来定义类。
2、面向接口编程,优先先定义好接口,入参和出参模型。调用接口,先弄清楚接口的入参和出参模型。
3、命名清晰,命名做到自我描述。但是包名、类名、方法名一定要定义的清楚明白,局部变量命名,不要过于纠结。
4、避免过长的方法参数,特别是public方法,原则上参数不超过三个,构造方法除外。
对于方法参数过长的,可以将方法参数抽象成类。如果这个类只有该方法用的到,可以使用静态成员类。
慎用可变参数,可变参数本质就是数组。对于业务方法来说,可变参数的方法,大多违背了单一原则,在后期往往不容易优化。
5、业务方法的长度要可控,有些业务可能很复杂,这个时候要学会抽取private方法,体现业务的主流程。
6、使用继承抽象公有的属性和逻辑,但继承的深度要可控、合理。组合代替继承
7、使用设计模式。模版方法、门面、责任连、代理、观察者等,能使代码更清晰,减少耦合。
具体的编码风格
先指出曾经认为对的编码规范。主要是告诫自己,遇到编码规范,不要盲从。
a、不要循环的创建对象的引用,如下代码,建议将引用定义在外边。实际上定义在内部和外部并没有区别,jvm并不会每次都创建一个引用。
for (int i = 1; i <= 1000; i++) { Object obj = new Object(); }
b、建议将list.size()单独定义成变量,原因是list每次都会计算size的大小。实际上对于ArrayList、LinkedList,都有size属性,list.size会直接返回size,并不是每次都计算size。当然定义成变量可以减少方法的调用,但对于方法的性能提升几乎可以忽略。
for (int i = 0; i < list.size(); i++) {...}
自己遵从的编码风格
1、保留字,方法和括号、运算符的空格要和ide一致,自己的代码要格式化
2、局部变量作用域最小化,在用到局部变量的时候在定义局部变量
3、接口方法不要加public,其本身就是public的。
4、使用for (;;) 代替while (ture)
5、契约编程,满足条件即返回。如从一个List中取值,取到即return,不要定义变量赋值。
public Object getNum() { for (int i = 0; i < list.size(); i++) { if (i == num){ return list.get(i); } } return null; }
6、减少if else的判断。避免双重否定的判断
public boolean isAdult(int age){ boolean isAdult = age > 18 && sex = "男"; return isAdult; }
7、基本类型优先于包装类型。装箱类型和基本类型做运算时(或者说使用运算符),总是会自动拆箱。对于二手代码,一定要注意,之前定义了包装类型,自己定义基本类型,可能会抛NPE。
Integer a1 = 1000;
Integer a2 = 1000;
int a3 = 1000;
System.out.println(a1 == a2);
System.out.println(a1 == a3);
8、对于if判断后逻辑只有一行的代码,不要换行
if (userName == null) throw new ArgumentException("user name can not be empty");
9、复杂的逻辑,可以使用函数对象取代函数,参见 https://my.oschina.net/u/134516/blog/127200
10、代码中不允许出现任何魔法值