java开发规范(不足请留言)

开发规范

开发规范原则

  • 规范。保证您的代码规范,保证结构表现行为相互分离。
  • 简洁。保证代码的最简化,避免多余的空格、空行,保持代码的语义化。任何时候都要用尽量简单、尽量少的元素解决问题。
  • 实用。遵循标准,但是不能以牺牲实用性为代价。
  • 忠诚。选择一套规范,然后始终遵循。不管代码由多少人参与,都应该看起来像一个人写的一样

1 Web开发规范

1.1 一般规范

文件/资源命名

  • 文件命名总是以字母开头而不是数字
  • 以减号(-)是用来分隔文件名,例:1001-scripts.js
  • 名称必须全为小写。因为在某些对大小写字母敏感的操作系统中,当文件通过工具压缩混淆后,或者人为修改过后,大小写不同而导致引用文件不同的错误,很难被发现。
  • 需要对文件增加前后缀或特定的扩展,使用“.”分隔符来区分,例如:my-file.min.css

不要指定引入资源所带的具体协议

不推荐:<script src="http://cdn.com/foundation.min.js"></script>
推荐:<script type="text/javascript" src="<%=request.getContextPath()%>/js/echarts.js"></script>
不推荐:.example {background: url(http://static.example.com/images/bg.jpg);}
推荐:.general-box{ background:url(../images/general.png);}

文本缩进:一次缩进4个空格

html 代码:
<ul>
<li>Fantastic</li>
<li>Great</li>
<li>
<a href="#">Test</a>
</li>
</ul>
css 代码:
.body {
font-size: 100%;
}
js 代码:
$(document).ready(function(){
$(".menu li").hover(function(){
$(this).addClass("hover");
$(this).children("ul li").attr('class','');
},function(){
$(this).removeClass("hover");  
$(this).children("ul li").attr('class','');
}
);

注释

不推荐:
//用户信息展示
function showOperaterMessage(data){
var url = getUrlRoot() + '/appView.do?method=appInfo' + data;
window.open(url);
}
推荐:
/** 用户信息展示 */
function showOperaterMessage(data){
var url = getUrlRoot() + '/appView.do?method=appInfo' + data;
window.open(url);
}

1.2 HTML规范

  • html标签、属性全部小写
  • 双标签必须闭合,单标签(自关闭标签)不闭合 <hr>
  • 属性值使用("")双引号,不要使用('')
  • html属性应该按照特定的顺序出现以保证易读性。class->id,name->data-*->src,for,type,href->title,alt->aria-*,role,value
  • 尽量避免<body></body>中编写javascript代码,例如
<table class="simple-table" id="opHistoryTable1">
    <tr>
<th width="100">时间</th>
<th width="70">IP状态</th>
<th>访问情况</th>
    </tr>
</table>
<script>
    $(".nicescroll2").niceScroll({
        cursorcolor : "#000",
        cursoropacitymax : 0.3,
        horizrailenabled : true,
        touchbehavior : false,
        cursorwidth : "10px",
        cursorborder : "0",
        cursorborderradius : "8px"
    });
</script>
  • 尽量避免使用style属性

1.3 CSS规范

层次结构

  • 全局global.css全局样式为全站公用,为页面样式基础,页面中必须包含。
  • 结构layout.css页面结构类型复杂,并且公用类型较多时使用。多用在首页级页面和产品类页面中。
  • 私有style.css独立页面所使用的样式文件,页面中必须包含。
  • 模块module.css产品类页面应用,将可复用类模块进行剥离后,可与其它样式配合使用。
  • 主题themes.css实现换肤功能时应用。

命名规范

  • 头:header
  • 内容:content/containe
  • 尾:footer
  • 导航:nav
  • 侧栏:sidebar
  • 栏目:column
  • 页面外围控制整体布局宽度:wrapper
  • 左右中:left right center
  • 登录条:loginbar
  • 标志:logo
  • 广告:banner
  • 页面主体:main
  • 热点:hot
  • 新闻:news
  • 下载:download
  • 子导航:subnav
  • 菜单:menu
  • 子菜单:submenu
  • 搜索:search
  • 友情链接:friendlink
  • 页脚:footer
  • 版权:copyright
  • 滚动:scroll
  • 内容:content
  • 标签页:tab
  • 文章列表:list
  • 提示信息:msg
  • 小技巧:tips
  • 栏目标题:title
  • 加入:joinus
  • 指南:guild
  • 服务:service
  • 注册:regsiter
  • 状态:status
  • 投票:vote
  • 合作伙伴:partner

其它

  • 命名统一采用小写;
  • 尽量用英文;
  • 不加中杠和下划线;
  • 尽量不缩写,除非一看就明白的单词
  • 定义颜色时使用颜色的名称或者16进制代码
  • 若有子标签样式,最好放在一起,例如:
.model{ margin:0 5px;}
.model li{ width:154px;}
  • 省略“0”值后面的单位,例如:margin: 0;
  • 不建议所有属性都写在同一行,例如:.model-cont ul li{  width:154px; height:36px; line-height:36px; background:#00a0e9;  margin:5px 0 0 10px; font-size:14px; color:#fff; pad...
     建议
.box {
    display: block;
    position: absolute;
    left: 30%;
    right: 30%;
    overflow: hidden;
    margin: 1em;
    padding: 1em;
    background-color: #eee;
    border: 3px solid #ddd;
    font-family: 'Arial', sans-serif;
    font-size: 1.5rem;
    text-transform: uppercase;
}
  • 最好能够遵循以下属性顺序
结构性属性:
display
position, left, top, right.
overflow, float, clear.
margin, padding
表现性属性:
background, border.
font, text

1.4 JavaScript规范

  • 变量和方法名采用首字母小写的驼峰式命名规则
  • 声明变量“=”前后最好添加空格,例:var a = 0;
  • 常量:必须采用全大写的命名,且单词以_分割
  • 类:必须采用骆驼峰的命名且首字母大写,例如:
// 正确的写法
var FooAndToo = function(name) {
this.name = name;
}
  • 每句代码后必须加";",例如:
a = b        // 赋值
(function(){
        //....
})()         // 自执行函数
未加分号会被解析成a = b(function(){//...})()  //b()()返回的结果赋值给a
  • 在同一个函数内部,局部变量的声明最好置于顶端,因为即使放到中间,js解析器也会提升至顶部
  • 空格的使用:
//推荐的写法
if (isOk) {
console.log("ok");
}
//不推荐的写法
if(isOk){
console.log("ok");
}
//推荐的写法
switch(name) {
//不推荐的写法
switch (name) {
//推荐的写法
for (i=0, len=names.length; i < len; i++) {
//不推荐的写法
for(i = 0, len = names.length;i < len;i++) {
//推荐的写法
var cell = function () {
//不推荐的写法
var call = function(name){ 
  • 块内函数必须用局部变量声明
    //不推荐的写法
    var call = function(name) {
        if (name == "hotel") {
            function foo() {
                console.log("hotel foo");
            }
        }
        foo && foo();
    }
    // 推荐的写法
    var call = function(name) {
        var foo;
        if (name == "hotel") {
            foo = function() {
                console.log("hotel foo");
            }
        } 
        foo && foo();
}
  • 不用使用eval,采取$.parseJSON,主要是因为:有注入风险,尤其是ajax返回数据;不方便debug;效率低,eval是一个执行效率很低的函数
备注:eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码。若莫名其妙给你注入一个<script src="">标签,或者一段来历不明的JSON-P请求,再或者就是Ajax请求中的eval代码,那就等着悲剧吧。
  • If…else…等不要简写
  • 推荐在需要以{}闭合的代码段前增加换行

2 后台开发规范

2.1 应用分层

  • 终端显示层:各个端的模板渲染并执行显示层。当前主要是velocity渲染,JS渲染,JSP渲染,移动端展示层等。
  • Web层:主要是对访问控制进行转发,各类基本参数校验,或者不复用的业务简单处理等。
  • Service层:相对具体的业务逻辑服务层。
  • DAO层:数据访问层,与底层MysqlOracleHbaseOB进行数据交互。外部接口或第三方平台:包括其它部门RPC开放接口,基础平台,其它公司的HTTP接口。
注意:
1DAO层一般与数据进行交互,产生的异常类型有很多,无法用细粒度异常进行try…catch,使用catch(Exception e)方式,并throw newDaoException(e),不需要打印日志。
2Service层出现异常时,必须记录日志信息,尽可能带上参数信息,相当于保护案发现场。
3Web层不应该继续往上抛异常,因为已经处于顶层,无继续处理异常的方式,特殊情况除外(应该直接跳转到友好错误页面,尽量加上友好的错误提示信息)
4)调用规范:终端显示层 -- Web -- Service -- DAO层,Service层和DAO层通过接口实现调用,不要直接调用实现类(若需要静态类,可直接调用静态类)
5)若有需要进行一些规则的校验,可放在Web层(简单数据校验)和Service层(业务逻辑校验)。

2.2 分层领域模型

  • DOData Object):与数据库表结构一一对应,通过DAO层向上传输数据源对象。
  • BOBusiness Object):业务对象。可以由Service层输出的封装业务逻辑的对象。
  • VOView Object):显示层对象,通常是Web向模板渲染引擎层传输的对象。
注意:定义分层领域模型时,不要设定任何属性默认值,也不要采用is开头的变量。

2.3 命名规范

  • 所有编程相关命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束。反例: _name / __name / $Object / name_ / name$ / Object$
  • 所有编程相关的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式。说明:正确的英文拼写和语法可以让阅读者易于理解,避免歧义。注意,即使纯拼音命名方式也要避免采用。反例: DaZhePromotion [打折] / getPingfenByName() [评分] / int 变量 = 3; 正例: ali / alibaba / taobao /cainiao / aliyun / youku / hangzhou 等国际通用的名称,可视为英文。
  • 杜绝完全不规范的缩写,避免望文不知义。反例:<某业务代码>AbstractClass“缩写命名成AbsClasscondition“缩写命名成 condi,此类随意缩写严重降低了代码的可阅读性。
  • 包命名:统一使用小写
  • 类命名:首字母大写的驼峰形式(UpperCamelCase),领域模型类的命名按类命名方式,以DO / BO / VO结尾,例如: MarcoPolo / UserDO / XmlService
  • 方法名、参数名、成员变量、局部变量:统一使用首字母小写的驼峰形式(lowerCamelCase),例如:localValue / getHttpMessage() / inputUserId
  • 常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚。例如: MAX_STOCK_COUNT 
  • 数组定义如下:String[] args; 勿使用String args[]的方式来定义
  • Service/DAO层方法命名:查询的方法用getquery作前缀,如果涉及获取多个对象,可以List作为后缀;统计值的方法以count作为前缀;插入的方法用save(推荐)或insert做前缀;删除的方法用remove(推荐)或delete做前缀;修改的方法用update做前缀。
  • 领域模型命名:数据对象:xxxDOxxx即为数据表名,如果表名带下划线,xxx去掉下划线;业务对象:xxxBOxxx为业务领域相关的名称;展示对象:xxxVOxxx一般为网页名称。

2.4 常量定义

  • 不允许出现任何未经定义的常量直接出现在代码中,例如:String key="Id#taobao_"+tradeId;
  • long或者Long初始赋值时,必须使用大写的L,不能是小写的l,小写容易跟数字混淆,造成误解。
  • 不要使用一个常量类维护所有常量,应该按常量功能进行归类,分开维护。如:缓存相关的常量放在类:CacheConsts下;系统配置相关的常量放在类:ConfigConsts下。
  • 常量的复用层次有五层:跨应用共享常量、应用内共享常量、子工程内共享常量、包内共享常量、类内共享常量。
1)跨应用共享常量:通常是架包中的const目录下。
2)应用内共享常量:放置在一方库的modules中的const目录下。
反例:易懂变量也要统一定义成应用内共享常量,两位工程师在两个类中分别定义了表示
的变量:
A中:public static final String YES ="yes";     
B中:public static final String YES = "y";
A.YES.equals(B.YES),预期是true,但实际返回为false,导致产生线上问题。
3)子工程内部共享常量:即在当前子工程的const目录下。
4)包内共享常量:即在当前包下单独的const目录下。
5)类内共享常量:直接在类内部private static final定义。

2.5 OOP规范

  • 避免通过一个类的对象引用访问此类的静态变量或静态方法,无谓增加编译器解析成本,直接用类名来访问即可。
  • 不要使用过时的类或方法
  • 循环体内,字符串的联接方式,使用StringBuilderappend方法进行扩展。
  • 类成员与方法访问控制从严:
1 如果不允许外部直接通过new来创建对象,那么构造方法必须是private
2 工具类不要有publicdefault构造方法。
3 类非static成员变量并且与子类共享,必须是protected 
4 类非static成员变量并且仅在本类使用,必须是private
5 static成员变量如果仅在本类使用,必须是private
6 若是static成员变量,必须考虑是否为final
7 类成员方法只供类内部调用,必须是private 
8 类成员方法只对继承类公开,那么限制为protected
注意:任何类、方法、参数、变量,严控访问范围。过宽泛的访问范围,不利于模块解耦。
  • 涉及表的增删改均需要异常处理
  • java文件约定
1)建议单个类的长度包括注释行不超过1500行。 尽量避免使用大类和长方法。
2)每行代码字数不超过150
3)类中的方法最好不要超过3个翻页,方便阅读
4)一个方法构造的参数个数不超过5个。
  • 异常处理
1)当捕捉到异常时,必须处理catch代码区,打印错误信息,统一用log4j统一日志输出
2)应该尽可能的精确捕捉异常。原因:精确的捕捉异常能够帮助你了解代码和确切知道你要做什么。
3try最多被嵌套3层。
  • 文件字符集统一使用UTF-8标准(包括JSP/HTML/CSS/.PROPERTIES)
  • 尽量使用StringBuffer,而不用String来累加字符串,因为String一旦初始化后是不能变的,所以在每执行一次+号时,相当于创建一个StringBuffer对象,然后append,最后返回一个String,所以在这个过程中无疑会增加系统的负担。
  • 能用基本类型如Int,Long,就不用Integer,Long对象
  • 尽量少用静态对象变量,静态对象过多造成大量占用java虚拟机的内存,影响系统的数据处理过程,甚者造成内存溢出,如果真的需要很多变量,可以采用xml文件配置方式
  • 判空方式:
字符串判空:
String a = "";
if (null != a && !a.equals("")) {
...
}
数组判空:
String[] a = null;
if(null != a && a.length > 0){
...
}
List对象判空
List list = new ArrayList();;
if (null != list && list.size() > 0) {
...
}
  • 变量一定要初始化

2.6 注释规范

  • 注释必须使用javadoc规范,使用/**内容*/格式,不要使用//xxx方式。
说明:在IDE编辑窗口中,javadoc方式会提示相关注释,生成javadoc可以正确输出相应注释;在IDE中,工程调用方法时,不进入方法即可悬浮提示方法、参数、返回值的意义,提高阅读效率。
  • 类最好注释类的作用和创建者信息。
  • 方法内部单行注释,在被注释语句上方另起一行,使用//注释。方法内部多行注释使用/* */注释,注意与代码对齐。
  • 所有的枚举类型字段必须要有注释,说明每个数据项的用途。
  • 与其半吊子英文来注释,不如用中文注释把问题说清楚。专有名词、关键字,保持英文原文即可。
  • 方法的注释如果有接口,一般在接口对于的方法法进行注释,没有则在方法上进行注释

2.7 日志规范

  • 谨慎地记录日志。生产环境禁止输出debug日志;有选择地输出info日志(关键的业务逻辑点)
  • 必须适用LOG作为日志处理,在重要环节要有入口和出口日志,对catch到的内容必须log报异常。

 

    1. 常见错误
1)入参和查询结果未判空,导致报空指针异常
错误示例:
for(int i=0;i<list.size();i++){
……
}
正确示例:
if(null != list && list.size() > 0){
for(int i=0;i< list.size();i++){
……
}
}
2)代码中包含SysTem.out.println
3)用“==”比较两个字符串内容相等
String a = new String("a");  
String a2 = "a";  
错误:a == a2
正确:a.equals(a2)
4)在foreach循环中修改list结构
for(Person p : list)   {  
if("王五".equals(p.getName()))   {  
list.remove(p); // 不能在此时删除对象。</span>  
}  
}
5)直接使用数据进行对比,让人不知其意(即魔鬼数字问题),例如:
错误:"1".equals(logType) || "7".equals(logType)
正确:(PickConst.LOG_TYPE_OPERATOR.equals(logType) || PickConst.LOG_TYPE_TRAFFIC.equals(logType))
6)数组越界异常:
String[] cIds;
错误:System.out.println(cIds[0] .toCharArray());
正确:if(null != cIds && cIds.length > 0) {
System.out.println(cIds[0] .toCharArray());
}
7)使用文件、IO流、数据库连接未将其关闭,且应该在try...catch...finallyfinally内执行
错误示例:
public voidwriteProduct1(ProductServiceStruct product) {  
    try{  
        FileWriter fileWriter = new FileWriter("");  
        fileWriter.append(product.toString());  
        // 如果append()抛出异常,close()方法就不会执行,造成IO流长时间无法释放  
        fileWriter.close();  
    } catch(IOException e) {  
        ...  
    }  
正确示例:
public voidwriteProduct2(ProductServiceStruct product) {  
    FileWriter fileWriter = null;  
    try {  
        fileWriter = new FileWriter("");  
        fileWriter.append(product.toString());  
    } catch(IOException e) {  
        ...  
       //记录日志  
    } finally {  
        // 不管前面是否发生异常,finally中的代码一定会执行  
        if(fileWriter != null)  {  
            try {  
                fileWriter.close();  
            } catch(IOException e) {  
                ...  
                //记录日志  
            }  
        }  
    }  
8)循环体内使用try...catch,应放在循环体外
9)使用错误的三元操作符,例:foo.toString()!==""?true:false;
10)对数据库进行更删改时,没有使用事务进行控制(一般是框架进行事务控制)

3. 具体规范要求

开发规范

开发规范原则

  • 规范。保证您的代码规范,保证结构表现行为相互分离。
  • 简洁。保证代码的最简化,避免多余的空格、空行,保持代码的语义化。任何时候都要用尽量简单、尽量少的元素解决问题。
  • 实用。遵循标准,但是不能以牺牲实用性为代价。
  • 忠诚。选择一套规范,然后始终遵循。不管代码由多少人参与,都应该看起来像一个人写的一样

1 Web开发规范

1.1 一般规范

文件/资源命名

  • 文件命名总是以字母开头而不是数字
  • 以减号(-)是用来分隔文件名,例:1001-scripts.js
  • 名称必须全为小写。因为在某些对大小写字母敏感的操作系统中,当文件通过工具压缩混淆后,或者人为修改过后,大小写不同而导致引用文件不同的错误,很难被发现。
  • 需要对文件增加前后缀或特定的扩展,使用“.”分隔符来区分,例如:my-file.min.css

不要指定引入资源所带的具体协议

不推荐:<script src="http://cdn.com/foundation.min.js"></script>
推荐:<script type="text/javascript" src="<%=request.getContextPath()%>/js/echarts.js"></script>
不推荐:.example {background: url(http://static.example.com/images/bg.jpg);}
推荐:.general-box{ background:url(../images/general.png);}

文本缩进:一次缩进4个空格

html 代码:
<ul>
<li>Fantastic</li>
<li>Great</li>
<li>
<a href="#">Test</a>
</li>
</ul>
css 代码:
.body {
font-size: 100%;
}
js 代码:
$(document).ready(function(){
$(".menu li").hover(function(){
$(this).addClass("hover");
$(this).children("ul li").attr('class','');
},function(){
$(this).removeClass("hover");  
$(this).children("ul li").attr('class','');
}
);

注释

不推荐:
//用户信息展示
function showOperaterMessage(data){
var url = getUrlRoot() + '/appView.do?method=appInfo' + data;
window.open(url);
}
推荐:
/** 用户信息展示 */
function showOperaterMessage(data){
var url = getUrlRoot() + '/appView.do?method=appInfo' + data;
window.open(url);
}

1.2 HTML规范

  • html标签、属性全部小写
  • 双标签必须闭合,单标签(自关闭标签)不闭合 <hr>
  • 属性值使用("")双引号,不要使用('')
  • html属性应该按照特定的顺序出现以保证易读性。class->id,name->data-*->src,for,type,href->title,alt->aria-*,role,value
  • 尽量避免<body></body>中编写javascript代码,例如
<table class="simple-table" id="opHistoryTable1">
    <tr>
<th width="100">时间</th>
<th width="70">IP状态</th>
<th>访问情况</th>
    </tr>
</table>
<script>
    $(".nicescroll2").niceScroll({
        cursorcolor : "#000",
        cursoropacitymax : 0.3,
        horizrailenabled : true,
        touchbehavior : false,
        cursorwidth : "10px",
        cursorborder : "0",
        cursorborderradius : "8px"
    });
</script>
  • 尽量避免使用style属性

1.3 CSS规范

层次结构

  • 全局global.css全局样式为全站公用,为页面样式基础,页面中必须包含。
  • 结构layout.css页面结构类型复杂,并且公用类型较多时使用。多用在首页级页面和产品类页面中。
  • 私有style.css独立页面所使用的样式文件,页面中必须包含。
  • 模块module.css产品类页面应用,将可复用类模块进行剥离后,可与其它样式配合使用。
  • 主题themes.css实现换肤功能时应用。

命名规范

  • 头:header
  • 内容:content/containe
  • 尾:footer
  • 导航:nav
  • 侧栏:sidebar
  • 栏目:column
  • 页面外围控制整体布局宽度:wrapper
  • 左右中:left right center
  • 登录条:loginbar
  • 标志:logo
  • 广告:banner
  • 页面主体:main
  • 热点:hot
  • 新闻:news
  • 下载:download
  • 子导航:subnav
  • 菜单:menu
  • 子菜单:submenu
  • 搜索:search
  • 友情链接:friendlink
  • 页脚:footer
  • 版权:copyright
  • 滚动:scroll
  • 内容:content
  • 标签页:tab
  • 文章列表:list
  • 提示信息:msg
  • 小技巧:tips
  • 栏目标题:title
  • 加入:joinus
  • 指南:guild
  • 服务:service
  • 注册:regsiter
  • 状态:status
  • 投票:vote
  • 合作伙伴:partner

其它

  • 命名统一采用小写;
  • 尽量用英文;
  • 不加中杠和下划线;
  • 尽量不缩写,除非一看就明白的单词
  • 定义颜色时使用颜色的名称或者16进制代码
  • 若有子标签样式,最好放在一起,例如:
.model{ margin:0 5px;}
.model li{ width:154px;}
  • 省略“0”值后面的单位,例如:margin: 0;
  • 不建议所有属性都写在同一行,例如:.model-cont ul li{  width:154px; height:36px; line-height:36px; background:#00a0e9;  margin:5px 0 0 10px; font-size:14px; color:#fff; pad...
     建议
.box {
    display: block;
    position: absolute;
    left: 30%;
    right: 30%;
    overflow: hidden;
    margin: 1em;
    padding: 1em;
    background-color: #eee;
    border: 3px solid #ddd;
    font-family: 'Arial', sans-serif;
    font-size: 1.5rem;
    text-transform: uppercase;
}
  • 最好能够遵循以下属性顺序
结构性属性:
display
position, left, top, right.
overflow, float, clear.
margin, padding
表现性属性:
background, border.
font, text

1.4 JavaScript规范

  • 变量和方法名采用首字母小写的驼峰式命名规则
  • 声明变量“=”前后最好添加空格,例:var a = 0;
  • 常量:必须采用全大写的命名,且单词以_分割
  • 类:必须采用骆驼峰的命名且首字母大写,例如:
// 正确的写法
var FooAndToo = function(name) {
this.name = name;
}
  • 每句代码后必须加";",例如:
a = b        // 赋值
(function(){
        //....
})()         // 自执行函数
未加分号会被解析成a = b(function(){//...})()  //b()()返回的结果赋值给a
  • 在同一个函数内部,局部变量的声明最好置于顶端,因为即使放到中间,js解析器也会提升至顶部
  • 空格的使用:
//推荐的写法
if (isOk) {
console.log("ok");
}
//不推荐的写法
if(isOk){
console.log("ok");
}
//推荐的写法
switch(name) {
//不推荐的写法
switch (name) {
//推荐的写法
for (i=0, len=names.length; i < len; i++) {
//不推荐的写法
for(i = 0, len = names.length;i < len;i++) {
//推荐的写法
var cell = function () {
//不推荐的写法
var call = function(name){ 
  • 块内函数必须用局部变量声明
    //不推荐的写法
    var call = function(name) {
        if (name == "hotel") {
            function foo() {
                console.log("hotel foo");
            }
        }
        foo && foo();
    }
    // 推荐的写法
    var call = function(name) {
        var foo;
        if (name == "hotel") {
            foo = function() {
                console.log("hotel foo");
            }
        } 
        foo && foo();
}
  • 不用使用eval,采取$.parseJSON,主要是因为:有注入风险,尤其是ajax返回数据;不方便debug;效率低,eval是一个执行效率很低的函数
备注:eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码。若莫名其妙给你注入一个<script src="">标签,或者一段来历不明的JSON-P请求,再或者就是Ajax请求中的eval代码,那就等着悲剧吧。
  • If…else…等不要简写
  • 推荐在需要以{}闭合的代码段前增加换行

2 后台开发规范

2.1 应用分层

  • 终端显示层:各个端的模板渲染并执行显示层。当前主要是velocity渲染,JS渲染,JSP渲染,移动端展示层等。
  • Web层:主要是对访问控制进行转发,各类基本参数校验,或者不复用的业务简单处理等。
  • Service层:相对具体的业务逻辑服务层。
  • DAO层:数据访问层,与底层MysqlOracleHbaseOB进行数据交互。外部接口或第三方平台:包括其它部门RPC开放接口,基础平台,其它公司的HTTP接口。
注意:
1DAO层一般与数据进行交互,产生的异常类型有很多,无法用细粒度异常进行try…catch,使用catch(Exception e)方式,并throw newDaoException(e),不需要打印日志。
2Service层出现异常时,必须记录日志信息,尽可能带上参数信息,相当于保护案发现场。
3Web层不应该继续往上抛异常,因为已经处于顶层,无继续处理异常的方式,特殊情况除外(应该直接跳转到友好错误页面,尽量加上友好的错误提示信息)
4)调用规范:终端显示层 -- Web -- Service -- DAO层,Service层和DAO层通过接口实现调用,不要直接调用实现类(若需要静态类,可直接调用静态类)
5)若有需要进行一些规则的校验,可放在Web层(简单数据校验)和Service层(业务逻辑校验)。

2.2 分层领域模型

  • DOData Object):与数据库表结构一一对应,通过DAO层向上传输数据源对象。
  • BOBusiness Object):业务对象。可以由Service层输出的封装业务逻辑的对象。
  • VOView Object):显示层对象,通常是Web向模板渲染引擎层传输的对象。
注意:定义分层领域模型时,不要设定任何属性默认值,也不要采用is开头的变量。

2.3 命名规范

  • 所有编程相关命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束。反例: _name / __name / $Object / name_ / name$ / Object$
  • 所有编程相关的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式。说明:正确的英文拼写和语法可以让阅读者易于理解,避免歧义。注意,即使纯拼音命名方式也要避免采用。反例: DaZhePromotion [打折] / getPingfenByName() [评分] / int 变量 = 3; 正例: ali / alibaba / taobao /cainiao / aliyun / youku / hangzhou 等国际通用的名称,可视为英文。
  • 杜绝完全不规范的缩写,避免望文不知义。反例:<某业务代码>AbstractClass“缩写命名成AbsClasscondition“缩写命名成 condi,此类随意缩写严重降低了代码的可阅读性。
  • 包命名:统一使用小写
  • 类命名:首字母大写的驼峰形式(UpperCamelCase),领域模型类的命名按类命名方式,以DO / BO / VO结尾,例如: MarcoPolo / UserDO / XmlService
  • 方法名、参数名、成员变量、局部变量:统一使用首字母小写的驼峰形式(lowerCamelCase),例如:localValue / getHttpMessage() / inputUserId
  • 常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚。例如: MAX_STOCK_COUNT 
  • 数组定义如下:String[] args; 勿使用String args[]的方式来定义
  • Service/DAO层方法命名:查询的方法用getquery作前缀,如果涉及获取多个对象,可以List作为后缀;统计值的方法以count作为前缀;插入的方法用save(推荐)或insert做前缀;删除的方法用remove(推荐)或delete做前缀;修改的方法用update做前缀。
  • 领域模型命名:数据对象:xxxDOxxx即为数据表名,如果表名带下划线,xxx去掉下划线;业务对象:xxxBOxxx为业务领域相关的名称;展示对象:xxxVOxxx一般为网页名称。

2.4 常量定义

  • 不允许出现任何未经定义的常量直接出现在代码中,例如:String key="Id#taobao_"+tradeId;
  • long或者Long初始赋值时,必须使用大写的L,不能是小写的l,小写容易跟数字混淆,造成误解。
  • 不要使用一个常量类维护所有常量,应该按常量功能进行归类,分开维护。如:缓存相关的常量放在类:CacheConsts下;系统配置相关的常量放在类:ConfigConsts下。
  • 常量的复用层次有五层:跨应用共享常量、应用内共享常量、子工程内共享常量、包内共享常量、类内共享常量。
1)跨应用共享常量:通常是架包中的const目录下。
2)应用内共享常量:放置在一方库的modules中的const目录下。
反例:易懂变量也要统一定义成应用内共享常量,两位工程师在两个类中分别定义了表示
的变量:
A中:public static final String YES ="yes";     
B中:public static final String YES = "y";
A.YES.equals(B.YES),预期是true,但实际返回为false,导致产生线上问题。
3)子工程内部共享常量:即在当前子工程的const目录下。
4)包内共享常量:即在当前包下单独的const目录下。
5)类内共享常量:直接在类内部private static final定义。

2.5 OOP规范

  • 避免通过一个类的对象引用访问此类的静态变量或静态方法,无谓增加编译器解析成本,直接用类名来访问即可。
  • 不要使用过时的类或方法
  • 循环体内,字符串的联接方式,使用StringBuilderappend方法进行扩展。
  • 类成员与方法访问控制从严:
1 如果不允许外部直接通过new来创建对象,那么构造方法必须是private
2 工具类不要有publicdefault构造方法。
3 类非static成员变量并且与子类共享,必须是protected 
4 类非static成员变量并且仅在本类使用,必须是private
5 static成员变量如果仅在本类使用,必须是private
6 若是static成员变量,必须考虑是否为final
7 类成员方法只供类内部调用,必须是private 
8 类成员方法只对继承类公开,那么限制为protected
注意:任何类、方法、参数、变量,严控访问范围。过宽泛的访问范围,不利于模块解耦。
  • 涉及表的增删改均需要异常处理
  • java文件约定
1)建议单个类的长度包括注释行不超过1500行。 尽量避免使用大类和长方法。
2)每行代码字数不超过150
3)类中的方法最好不要超过3个翻页,方便阅读
4)一个方法构造的参数个数不超过5个。
  • 异常处理
1)当捕捉到异常时,必须处理catch代码区,打印错误信息,统一用log4j统一日志输出
2)应该尽可能的精确捕捉异常。原因:精确的捕捉异常能够帮助你了解代码和确切知道你要做什么。
3try最多被嵌套3层。
  • 文件字符集统一使用UTF-8标准(包括JSP/HTML/CSS/.PROPERTIES)
  • 尽量使用StringBuffer,而不用String来累加字符串,因为String一旦初始化后是不能变的,所以在每执行一次+号时,相当于创建一个StringBuffer对象,然后append,最后返回一个String,所以在这个过程中无疑会增加系统的负担。
  • 能用基本类型如Int,Long,就不用Integer,Long对象
  • 尽量少用静态对象变量,静态对象过多造成大量占用java虚拟机的内存,影响系统的数据处理过程,甚者造成内存溢出,如果真的需要很多变量,可以采用xml文件配置方式
  • 判空方式:
字符串判空:
String a = "";
if (null != a && !a.equals("")) {
...
}
数组判空:
String[] a = null;
if(null != a && a.length > 0){
...
}
List对象判空
List list = new ArrayList();;
if (null != list && list.size() > 0) {
...
}
  • 变量一定要初始化

2.6 注释规范

  • 注释必须使用javadoc规范,使用/**内容*/格式,不要使用//xxx方式。
说明:在IDE编辑窗口中,javadoc方式会提示相关注释,生成javadoc可以正确输出相应注释;在IDE中,工程调用方法时,不进入方法即可悬浮提示方法、参数、返回值的意义,提高阅读效率。
  • 类最好注释类的作用和创建者信息。
  • 方法内部单行注释,在被注释语句上方另起一行,使用//注释。方法内部多行注释使用/* */注释,注意与代码对齐。
  • 所有的枚举类型字段必须要有注释,说明每个数据项的用途。
  • 与其半吊子英文来注释,不如用中文注释把问题说清楚。专有名词、关键字,保持英文原文即可。
  • 方法的注释如果有接口,一般在接口对于的方法法进行注释,没有则在方法上进行注释

2.7 日志规范

  • 谨慎地记录日志。生产环境禁止输出debug日志;有选择地输出info日志(关键的业务逻辑点)
  • 必须适用LOG作为日志处理,在重要环节要有入口和出口日志,对catch到的内容必须log报异常。

 

    1. 常见错误
1)入参和查询结果未判空,导致报空指针异常
错误示例:
for(int i=0;i<list.size();i++){
……
}
正确示例:
if(null != list && list.size() > 0){
for(int i=0;i< list.size();i++){
……
}
}
2)代码中包含SysTem.out.println
3)用“==”比较两个字符串内容相等
String a = new String("a");  
String a2 = "a";  
错误:a == a2
正确:a.equals(a2)
4)在foreach循环中修改list结构
for(Person p : list)   {  
if("王五".equals(p.getName()))   {  
list.remove(p); // 不能在此时删除对象。</span>  
}  
}
5)直接使用数据进行对比,让人不知其意(即魔鬼数字问题),例如:
错误:"1".equals(logType) || "7".equals(logType)
正确:(PickConst.LOG_TYPE_OPERATOR.equals(logType) || PickConst.LOG_TYPE_TRAFFIC.equals(logType))
6)数组越界异常:
String[] cIds;
错误:System.out.println(cIds[0] .toCharArray());
正确:if(null != cIds && cIds.length > 0) {
System.out.println(cIds[0] .toCharArray());
}
7)使用文件、IO流、数据库连接未将其关闭,且应该在try...catch...finallyfinally内执行
错误示例:
public voidwriteProduct1(ProductServiceStruct product) {  
    try{  
        FileWriter fileWriter = new FileWriter("");  
        fileWriter.append(product.toString());  
        // 如果append()抛出异常,close()方法就不会执行,造成IO流长时间无法释放  
        fileWriter.close();  
    } catch(IOException e) {  
        ...  
    }  
正确示例:
public voidwriteProduct2(ProductServiceStruct product) {  
    FileWriter fileWriter = null;  
    try {  
        fileWriter = new FileWriter("");  
        fileWriter.append(product.toString());  
    } catch(IOException e) {  
        ...  
       //记录日志  
    } finally {  
        // 不管前面是否发生异常,finally中的代码一定会执行  
        if(fileWriter != null)  {  
            try {  
                fileWriter.close();  
            } catch(IOException e) {  
                ...  
                //记录日志  
            }  
        }  
    }  
8)循环体内使用try...catch,应放在循环体外
9)使用错误的三元操作符,例:foo.toString()!==""?true:false;
10)对数据库进行更删改时,没有使用事务进行控制(一般是框架进行事务控制)

3. 具体规范要求

 

前端

后端

文件夹/包名

小写

文件名

  • 首字母小写的驼峰式
  • 文件名最好前后端相一致,例如:AloneModel.jsAloneModelActionAloneModelServiceAloneModelServiceImpl

文件层级

WebContent/模块名

WebContent/模块名/js

WebContent/模块名/css

WebContent/模块名/细模块

com.dragonsoft.模块名

com.dragonsoft.模块名.文件名Action

com.dragonsoft.模块名.文件名Service

com.dragonsoft.模块名.文件名ServiceImpl

(若有模块内通用方法,请在模块内另外存放)

公共类

WebContent/common(公共jsp

WebContent/css(公共样式)

WebContent/js(公共js

WebContent/image(存放图片)

WebContent/charts

com.dragonsoft.commons,存放通用类,比如:

com.dragonsoft.commons.const——通用静态常量类

com.dragonsoft.commons.model——通用实体类

com.dragonsoft.commons.util——通用方法类

com.dragonsoft.commons.dao——通用dao层实现类

com.dragonsoft.commons.service——通用服务层类

常量类命名

大写以_分割

方法命名

  • 首字母小写的驼峰式
  • 查询:query开头
  • 对象:List/Map结尾
  • 更新:update开头
  • 删表:drop开头
  • 删除:delete开头
  • 建表:create开头
  • 数组:Array结尾
  • 校验:check开头
  • 方法名相一致,例如:前后端均采用queryModeList()
  • 方法参数不超过5

注释

单行://

方法:/**内容*/

判空

字符串:!obj && obj !== ''

数组:null != arr && arr.length > 0

对象:null != obj && obj.length > 0

字符串:null != a && !a.equals(“”)

数组:null != arr && arr.length > 0

list对象:null != list && list.size() > 0

实体类

--

  • 不要设定任何属性默认值
  • Boolean属性,不允许is开头

其它

禁止出现:console.log(“”)

禁止出现:System.out.println(“”)

  • 文件行数限制:3000
  • 方法行数限制:150行,换行时遵循以下原则:

1 换行时相对上一行缩进4个空格。

2 运算符与下文一起换行。

3 方法调用的点符号与下文一起换行。

4 在多个参数超长,逗号后进行换行。

5  在括号前不要换行

  • 单行字符数限制:150字符
  • 左大括号前不换行。
  • 左大括号后换行。
  • 右大括号前换行
  • 右大括号后还有else等代码则不换行;表示终止右大括号后必须换行
  • 左括号和后一个字符之间不出现空格;同样,右括号和前一个字符之间也不出现空格
  • if/for/while/switch/do等保留字与左右括号之间都必须加空格
  • 任何运算符左右必须加一个空格
  • 代码块缩进4个空格,如果使用tab缩进,请设置成1tab4个空格
  • if/else/for/while/do语句中必须使用大括号,即使只有一行代码
  • if/else/for/while/do不超过三层
  • 多个同名方法,这些方法应该按顺序放置在一起,便于阅读
   
   
   
     
     
   
   
 
   
     
     
     
 
 
 
 

猜你喜欢

转载自blog.csdn.net/wmr820394977/article/details/81127026