读开发规范有感

来源:互联网 发布:怎样在淘宝上进货 编辑:程序博客网 时间:2024/06/03 11:41

读开发规范有感

最近读了师傅写的开发手册深有感触,里面写了很多开发需要注意的地方,还有很多技巧,更多的是开发规矩,这样开发的意思。

首先我们为什么要开发规范

第一点,是开发代码规范,代码机构清晰,便于后其维护,更有助于代码重构,好处之大,可想而知,一个项目的生命周期,百分之八十在项目维护上。

第二地,规范的 代码,让人赏心悦目,更能体现出开发者的水平,也能表现出整体团队的实力程度。

编码环境约定发

开发代码统一编码采用UTF-8

数据源链接:jdbc:mysql://ip:port/dbname?charaterEncoding=utf-8

Java编码:utf-8

jsp文件:utf-8

Xml文件:utf-8

Properties文件:utf-8

构建工具

基于maven进行项目构建,用Jenkins来做系统发布和持续集成

DB

应用MySQL配置链接,密码进行加密

IDE

l IntelliJ IDEA

l Eclipse

命名原则

l 见名知意

l 拼写准确

l 在语义表达清楚的情况下,字符尽量少用

工程,模块命名

l 全部小写

多个工程前缀相同,后缀用-”隔开

包命名

l 全部小写,避免使用下划线等特殊字符

“公司域名+(项目组名)+项目名称+(子项目名称)+模块名称”。按照实际开发,减少层级

优先使用web,model,domain,dao,service,business,controller,common,listener,cost,util,proxy,api”等词汇进行命名

实现包类用impl结尾

类命名

骆驼拼写法(UpperCamelCase),形成驼峰式,更有助于读取理解

接口实现类用impl结尾

抽象类命名使用Abstract或者Base为前缀

类结构采用设计模式,可加上设计模式的前缀。如FactoryProxyStrategyAdapterFacade”等 词语

l 根据性质,类型,职能进行划分,划分如下:

功能

后缀

实例

数据对象

PO或者DO

UserPO,UserDO

业务对象

BO

UserBO

展示对象

VO

UserVO

请求对象

Req

UserReq

响应对象

Resp

UserResp

数据访问实现类

DaoImpl

UserDaoImpl

业务逻辑处理实现类

ServiceImpl

UserServiceImpl

远程服务实现类

ClientImpl

UserClientImpl

控制器

Controller

UserController

工具类

Utils

StringUtils

单元测试类

Test

UserServiceTest

工厂类

Factory

RuleFactory

Filter

Filter

CroeFilter

Servlet

Servlet

UserServlet

监听器

Listener

CreaterOrderListener

方法命名规范

使用lowerCamelCase风格,遵循驼峰形式。

以动词+名词形式命名,如:findUserById

Dao 层方法命名

单条件查询,以select(推荐),find,query,get作为前缀

多条件查询,以list(推荐),query,select作为前缀

插入操作,以save(推荐),insert作为前缀

删除操作,以remove(推荐),delete作为前缀

更新操作,以update作为前缀

统计数值,以count作为前缀

批量操作,以batch作为前缀

变量命名

成员变量、局部变量、方法参数使用lowerCamelCase风格,遵循驼峰形式。

局部变量命名名可以一定程度使用缩写。

常量全部大写,单词间用下划线分隔。

l 如果是集合或数组,⽤名词复数

代码风格

通用原则

追求代码结构美学。

不要省略,可选大括号也加上。

if, else, for, do, while语句一起使用,即使只有一条语句,也建议把大括号写上.

左大括号前不换行,左大括号后换行,右大括号前换行

 

源文件结构

package语句

每个package语句独立成行。

import语句

每个import独立成行。

不要使用通配符,比如import java.util.*

写注释的原则

释不宜过多。注释固然重要, 但好的代码应当本身就是文档。有意义的命名, 要远胜过要用注释解释的含糊不清的名字。

需要注释解释的代码尽量提成小方法,用方法名称解释。

注释不应该只是浅显的描述,注释要描述代码背后的意图。

注释要简洁,不要封闭在由星号或其它字符绘制的框架里。

应用了高级技巧的地方尽量写上注释

注释要言简意赅, 不要拖沓冗余, 复杂的东西简单化和简单的东西复杂化都是要被鄙视的

注释应与代码保持同步

注释是为了让别人看懂,用中文吧

单元测试

测试代码和生产代码需遵守相同代码规范。

尽量写更多的单元测试

测试类的命名以它要测试的类的名称开始,以Test结尾。如StdPriceUtilsTest

单数据断言, 应使用assertTrue, assertFalse, assertNull, assertNotNull。

多数据断言, 应使用assertThat。

精确断言, 尽量不使用not, containsString断言。

调用业务方法的变量, 应命名为actualXXX, 期望值应命名为expectedXXX。

只有junit assertXXX, hamcrest, mocktio相关可以使用static import。

基于maven构建的工程,测试类放在src/test/java目录下,测试类包名和要测试的类包名一致。

异常规范

异常不要用来做流程控制。

为抛出的异常写注释,写文档。

如果要声明异常。一定要声明具体的异常,避免泛化的Exception。

尽量捕获具体的异常,而不是捕获泛化的Exception。

避免空的catch块吞噬掉异常。至少需要记录日志(确实不需要向上抛时),以供查看分析。

catch之后封装成新异常抛出的时候, 不要记录日志. 抛出的异常会有上层来处理并记录日志, 再记录日志就重复了。

不要在finally块中抛出异常

不要使用e.printStackTrace()。

finally程序块中关闭或者释放资源。

优先使用标准异常或错误。如IllegalArgumentException,IllegalStateException,UnsupportedOperationException,NoSuchElementException,FileNotFoundException、AssertionError等。

不要把异常放置在循环体内。try-catch语句本身性能不高,在开发中,要尽量避免。

不要在只读操作中轻易抛出异常。没有数据时,要返回长度为0的数组或列表。如:return Collections.emptyList()。只读结果让调用者来确定如何处理。

如果你认为调用者不能通过try…catch来处理你抛出的异常,要使用非受检查异常。对可恢复的情况使用受检异常,对编程错误使用运行时异常。

要做异常包装。工程内要有统一的异常体系。如BossBizException,BossServiceException,RuleTypeUnsupportedException等。

基于mybatis的Dao层不需要显式抛出异常;Service要捕获异常dao层异常,并抛出可读的业务异常。

Service层捕获了异常后,一定要重新抛出一个新的异常,这个异常最好是运行时异常,否则可能会影响的声明式事务的执行。

Web MVC开发中要使用全局的异常处理。

日志规范

采用slf4j + logback日志组件,这是当下最好的组合

日志变量定义推荐如下。

private static final Logger logger = LoggerFactory.getLogger(ChargeServiceImpl.class);

private static final Logger noCalcCostPriceLogger = LoggerFactory.getLogger("noCalcCostPriceLogger");

不要因为记录日志,导致系统异常,从而导致正常的业务逻辑被中断。是否会引起NPE?是否会导致OOM(比如输出巨大的列表)?是否会因打印无效日志造成磁盘被打爆?等等。

一般来说,日志只记录有效的方便定位问题的信息,比如只记录对象的id,只记录列表的长度等。忌直接输出整个对象的toString。

要使用参数化(占位符)方式记录日志,不要使用拼接字符串的方式。原因:代码较乱,不易一眼看出日志格式;字符串拼接,性能较差。

不要写魔法日志。有些开发人员为查找信息方便,会输出一些类似&&###>>>>>>。这是一种陋习,要避免。

不要将异常直接显示在页面或客户端。

日志文件命名规范

代码中只是用ERROR、WARN、INFO、DEBUG这几个日志级别

生产环境默认使用INFO级别。

关注日志记录对于系统性能、安全性的影响

禁止使用System.out、System.err、 e.printStackTrace()输出日志

避免重复输出日志,浪费磁盘空间。在logback.xml中设置additivity=false。

<logger name="com.kscloud.boss" level="info" additivity="false">

<appender-ref ref="dayLogAsyncAppender" />

<appender-ref ref="error"/>

<appender-ref ref="warn"/>

</logger>

正确的使用输出模式。生产环境,不要在日志中输出文件名、类全名、方法名、行号、Logger全名。在日志模式中指定文件名、类全名、方法名、行号会带来严重的性能问题。

生产环境关掉ConsoleAppender。生产环境输出到控制台是完全没有必要的,既浪费磁盘空间,又损耗性能。

logback去掉ch.qos.logback.core.ConsoleAppender

log4j去掉org.apache.log4j.ConsoleAppender

生产、开发、测试等环境的日志配置文件要做分离。

要做日志分离。按日志级别输出到不同文件中,比如错误(error)和警告(warn)日志输出到单独的文件中;针对访问日志、性能统计、个性化的业务,也可以输出到独立的文件中。方便查找和定位问题

需要输出日志的一些地方。

请求入口和出口

与第三方接口的交互(调用和返回)

程序异常:如数据库无法连接

用户访问统计:用户IP、上传下载的数据量,请求耗时等

启动、关闭、配置加载(系统在启动过程中通常会首先读启动参数,可以在系统启动后将这些参数输出到日志中,方便确认系统是按照期望的参数启动的)

审计、安全操作日志

性能统计日志

后台定期执行的任务:如定期更新缓存的任务,可以记录任务开始时间,任务结束时间;缓存配置的更新等等,这样可以掌握定期执行的任务的状态;

并发编程指导原则

如果需要频繁创建线程,考虑使用线程池,而不是使用最原始的Thread。用Executors.newSingleThreadExecutor代替new Thread吧。

永远为线程取一个有意义的名称,方便问题诊断。

并发编程最好先做数据分离,每个线程处理不同的数据,减少数据的同步。

优先使用JUC中的CountDownLatch、CyclicBarrier等工具。

计数器优先使用原子类,非阻塞,以获得最好的性能。

注意非线程安全的SimpleDateFormat。

使用ThreadLocal保存状态变量。

合理使用volatile。

CountDownLatch要避免在countDown方法之前遇到异常,导致countDown没被执行,永远等待。

安全编码指导原则

通用

敏感数据如密码,加盐哈希存储应该是标配。

永远不要信任用户输入,对用户输入数据做后端要有效性的检查。

严格控制文件上传,文件类型判断不能仅根据文件后缀确定。

源码中不出现密码,配置文件中也不要出现密码(要加密)。

注意敏感信息的保护。

用户的敏感信息包括密码、短信验证码、支付验证码、身份证号、银行卡号、银行密钥,商户密钥等信息;用户敏感信息不能泄露,否则可能会带来不安全因素。

可能会导致敏感信息泄露的方式有:Logger、URL的get参数(因为 URL 的get 参数会在nginx和tomcat 日志中被输出)。敏感信息输出要打码(***输出)。

 

原创粉丝点击