读阿里巴巴Java开发手册v1.2.0之编程规约有感【架构篇】
不为过去蹉跎,改变当下。
为什么开篇就送这么一句话给大家,我相信很多处于1-3年码龄的哥们儿们,在平时的编码历程中编码的个性可能是多彩的,每个人都有每个人特定的风格,但是我们现在这么随意写,以后这么随意写,好没问题,但是等你离开这个公司了或者是去开发别的项目了,再等别人过来接手维护你一手写出来的这段个性十足的代码时,那么你的右眼皮时不时地就会跳,因果我就不说了~~
所以我建议看到这篇博文的朋友们,或许你稍微改变一下你的编码风格,遵从一套好的编码规约对己对人都是有好处的。可能朋友的公司也有专门的编码规约,但是逃不了我们平时在开发一些属于自己的项目,比如有一天从李智慧老师的《大型网站技术架构:核心原理与案例分析》著作中学到一些非常好的东西,那么我们就想开始动手编码来实现一下,这时候如果尽量遵从一套很好的编码规约风格,将写出来的代码分享给身边的同事学习一下,提提建议多好。
2017-05-20这一天,阿里巴巴集团技术团队终于发布了版本号:1.2.0的Java开发手册,在这之前他们总共发布过5个版本,都有幸被我看到了。当时在地铁上一贯地翻开手机,直接打开《阿里技术》微信公众号,就一眼瞅到了"抢鲜下载|阿里Java开发手册最新完美版,千锤百炼始出炉——阿里巴巴Java开发手册v1.2.0",当时第一反应就是赶紧先拿到它,接着迅速找到下载入口,完美地保存在手机上了。
快速飘过前言,手册的愿景就是码出高效,码出质量。所谓无规矩不成方圆,无规范不能协作。质量的提升是告诉我们尽可能少踩坑,少吃那些无用的亏,高效协作即降低协同成本,提升沟通效率,再说现在的软件架构都需要多个程序员协同开发完成,公司也不可能让某个技术大牛独自去完成,所以让大家统一方式一起做事,才能提升开发效率。
手册结构总共由5部分组成:编程规约、异常日志、MySQL数据库、工程结构和安全规约。
一:编程规约
首先来说说编程规约吧,这部分是我个人极力推荐各位朋友能够借鉴,一个程序员有一个好的编码风格,真的是异于其他码农。我们谁都想要一个好听的名字,除了好听这个名字它还要有特殊的意义。在编码的过程中我们定义一个变量也是一样的,假如你定义的变量很烂,被人看到不仅会鄙视你,还会从心里认为你没文化,就算我们英文不好,但是也可以百度啊,让人看到一眼就能见名知意,多和谐啊~~
1、命名风格:
见名知意;类名、方法名、参数名、成员变量和局部变量使用驼峰式(但是这里强调一下,我们项目中难免会有很多分层领域的模型类,比如DO/BO/DTO/VO/AO,这些可以使用UserDO、QueryVO等形式);常量名大写;抽象类命名以Abstract或Base开头;异常类命名使用Exception结尾;测试类以Test结尾;包名统一使用小写;接口中的方法和属性尽量不要加任何修饰符(如果可以public也不要加),为了代码简洁;任何pojo类中布尔类型的变量,不要使用is做前缀,否则部分框架解析会引起序列化错误。
我们现在软件项目大部分都是分层的,对各个层中的方法和模型类地命名也有一定的讲究,Service/DAO层中各方法的命名:获取单个对象的方法采用get做前缀;获取多个对象的方法采用list做前缀;获取统计值的方法采用count做前缀;插入的方法采用save或insert做前缀,但是推荐使用save;删除的方法采用remove或delete做前缀,但是推荐使用remove;修改的方法采用update做前缀。Service/DAO层中各模型类的命名:数据对象采用XXXDO,一般和数据库中的表名对应;数据传输对象采用XXXDTO,一般是与业务领域相关的传输对象;视图层展示对象采用XXXVO,一般用于传递到视图层。
2、代码格式:
(1)、if语句的使用方面,小括号内的俩端不要出现空格并且if关键字后面添加一个空格(不光是if关键字,在if/for/switch/while/do关键字后面都要有空格);
(2)、在二目、三目运算符的左右都建议添加一个空格,比如=、==、&&、+-/*等运算符左右都应该添加空格;
(3)、在代码缩进方面,尽量不要使用tab键,建议使用4个空格缩进,如果单行代码超过120个字符,则建议换行;
(4)、多个参数同时传递时,逗号前建议有个空格;
3、OOP规约:
访问此类的静态变量或静态方法时,直接使用类名访问,无须通过对象引用访问此类的静态资源,如果你使用对象引用访问则无谓增加编译器解析成本;所有的覆盖方法必须添加@Override注解;在使用object类的equals方法时,尽量使用确定的值来调用equals方法,避免出现空指针异常(参考下图代码);所有的pojo类的属性必须使用包装类;定义任何pojo类的属性时,不要设定任何属性的默认值;构造方法中进制加入任何业务逻辑代码;建议所有的pojo类都添加toString()方法,方便排查问题。
4、并发处理:
获取单例对象需要保证线程安全,其中的方法也要保证线程安全;线程资源需要通过线程池获取,不建议显式创建线程;对多个资源、数据库表、对象同时加锁时,需要保持一致的加锁顺序,否则可能会造成死锁。
5、注释规约:
首先所有的类都应该添加创建者和创建日期;方法内部添加注释时,尽量采用单行注释,注释添加在被注释的代码上方,如果强制使用多行/**/注释,则应该与代码对齐;所有的抽象方法和接口中的方法,都必须在方法上面采用多行注释/***/解析清楚该方法是用来干什么的,实现了什么功能;如果某个方法的功能还未完善,则必须添加待办事宜TODO注释。
二:异常日志
对于异常日志这部分,我们绝对不能忽视,你不敢保证你写出的代码永远不会挂吧,那么我们就必须借助日志的力量来快速定位到问题的位置,以便解决。
1、异常处理:
对大段代码进行try-catch,这是不负责任的表现,我们应该精确处理,建议尽量将try块的代码放到事务代码中,一旦代码抛出异常,则必须回滚事务,一定要注意手动回滚事务;如果代码中使用到流等资源finally块必须对它们进行关闭,必须做,而且在关闭的时候如果可能出现异常则必须进行try-catch处理;不能在finally块中使用return语句。
2、日志规约:
我们平时的开发过程中,避免不了定时查看日志,分析日志,建议日志文件中的内容必须保存在15天以上,因为有些异常具备以“周”为频次发生的特点;推荐对日志进行分类,将系统运行产生的错误日志和系统运行产生的业务日志分开存储,方便开发人员查看;谨慎的记录日志,生产环境禁止输出debug日志,有选择性的输出info日志,一定要注意日志输出量的问题,避免把硬盘撑爆。
三:MySQL数据库
作为一名Java开发程序员,样样都得会点儿,不仅得辛苦的敲代码,而且还要具备大局观有时候还需要你来设计库结构和表关系,但是这时候我们尽量不要随意来搞,说不好听了你一旦随意起来,那么有一天你会前功尽弃地,因为我们的程序大多都是依托数据来运行的,所以,朋友们如果真要你遇上设计库表时,请认真对待。
(1)、建表规约:
首先在命名上,如果某个表的字段代表是与否的概念,则应该用is_XXX的方式开头,数据类型应该是unsigned tinyint(1表示是、0表示否);表名和字段名应该使用小写或数字,但是不能以数字开头,切记数据库中的字段名修改起来代价可是非常大的,因为无法进行预发布,所以在建表时命名字段名称时一定要慎之又慎;表名不适用负数名词,我们在开发中习惯将表名定义成负数名词,代表多个记录的统称,这样是不建议的;如果某个字段的数据类型为小数时,建议定义成decimal,不建议使用float或double,因为float或double有可能存在精度丢失,在进行的值的比较时会得到错误的结果,如果存储的数据超过decimal数据类型的存储范围时,建议将整数和小数分开存储;如果存储的字符串长度几乎相等,则建议使用定长char;创建一张表,必备的三个字段:id(主键)、gmt_create(创建时间)、gmt_modified(修改时间);表的命名一般建议是加上业务名称来作为表前缀;表中的字段允许存在冗余,以便提高查询效率,但是不能是varchar超长长度,更不能是text数据类型;单表行数超过500万行或大小超过2GB时,才建议分库分表。
(2)、索引规约:
业务上具有唯一特性的字段,或者是多个字段的组合,也必须建成唯一索引;在查询时超过3张表禁止使用join,需要join的字段,数据类型必须一致,多表关联查询时,保证被关联的字段需要有索引;页面搜索禁止走左模糊或者全模糊,如果需要应该搜索引擎来解决;如果有order by的场景,请注意利用索引的有序性,order by最后的字段是组合索引的一部分,并且放在索引组合顺序的最后,避免出现file_sort的情况,影响查询效率;SQL性能优化的目标:至少达到range级别(对索引进行范围检索)、要求是ref级别(指的是使用普通的索引)、如果可以的达到consts(单表中只有一个行匹配,即主键或唯一索引,在优化阶段即可读取到数据)最好;防止因字段类型不同导致的隐式转换,导致索引失效。
(3)、SQL语句:
我们在书写sql语句时大多数人都存在一个习惯,就是用count(列名)或count(常量)来代替count(*),count(*)是SQL92定义的标准的统计行数的语法,跟数据库无关,跟NULL和非NULL有关,请记住这句话:count(*)会统计值为NULL的记录,但是count(列名)是不会统计NULL的记录,导致数据读取错误;在代码中写分页查询逻辑时,若总计录数为0时,应该直接返回,避免执行后面的分页语句;禁止使用存储过程,因为存储难以调试和扩展,更没有移植性;我们在进行删除或修改记录时,要学会先select一下,接着再做delete或update也不迟,以免眼疾手快造成毁灭性的灾难;在使用in关键字是能避免则尽量避免,如果避免不了,应该仔细评估in后面的集合元素数量,尽量控制在1000以内,以免影响查询效率。
(4)、ORM映射:
在mapper文件中进行全表查询时,一律不要使用*号,需要哪些字段则应该明确写明;pojo类中的属性不应该以is开头,但是数据库中的字段名称必须以is_XXX开头,这时可以在resultMap中进行字段和属性的映射;在mapper文件中尽量不要使用${},应该使用#{},以免造成SQL注入问题;不允许直接拿HashMap和HashTable作为查询结果的输出;@transactional注解尽量不要滥用,事务会影响数据库的QPS,另外使用事务的地方,必须要考虑好事务回滚的最优方案,包括缓存回滚、搜索引擎回滚、消息补偿和统计修正等问题;
四:安全规约
我们在开发中不仅要最求效率和质量,也要做到百毒不侵,做好系统的安全工作。一般系统中牵扯到用户个人的页面或者功能时必须做权限校验;用户的一些敏感数据不能直接展示,必须对展示数据进行脱敏;用户输入的SQL参数必须严格进行参数绑定或者metadata字段值限定的操作,防止发生SQL注入的问题,切记:禁止允许用户使用字符串拼接SQL的方式来访问数据库,这危害可就大了去了~~,在开发中用户请求传入的参数必须做有效性验证,如果有必要则实现双重校验,即前后台校验,忽略参数校验,可能会导致page size过大导致内存溢出、恶意order by导致数据库慢查询、任意重定向、反序列化注入等问题;禁止向HTML页面输出未经安全过滤或位正确转义的用户数据;表单、AJAX提交必须执行CSRF安全过滤(CSRF是一类常见的编程漏洞,意为跨站请求伪造,对于存在CSRF漏洞的网站或应用,攻击者可以事先构造好URL,只要受害者用户一旦访问网站或应用,后台便在用户不知情的情况下对数据库中用户参数进行相应的修改);在使用平台资源,譬如短信、邮件、电话、下单和支付等业务场景时,必须实现正确的防重放限制,比如数量的限制、疲劳度控制、验证码校验,避免被滥刷,资损等情况。
干到这儿我本人学到的一些经验全部分享完毕,能力有限,总结的可能不太到位,希望各位读者见谅!
读阿里巴巴Java开发手册v1.2.0之编程规约有感【架构篇】的更多相关文章
- 读阿里巴巴Java开发手册v1.2.0之工程结构有感【架构篇】
首先,把昨天那俩条sql语句的优化原因给大家补充一下,第一条效率极低,第二条优化后的,sql语句截图如下: 经过几个高手的评论和个人的分析: 第一条sql语句查询很慢是因为它首先使用了in关键字查询, ...
- 《阿里巴巴Java开发手册v1.2》解析(编程规约篇)
之前在乐视天天研究各种底层高大上的东西,因为我就一个人,想怎么弄怎么弄.如今来了新美大,好好研读一下<阿里巴巴Java开发手册v1.2>.还要对这么看似简单的东西解析一番.毕竟现在带团队, ...
- 阿里巴巴 Java开发手册1.4.0
<阿里巴巴Java开发手册1.4.0>下载地址: 下载地址:https://102.alibaba.com/downloadFile.do?file=1528269849853/Java_ ...
- 码出高效,阿里巴巴JAVA开发手册1.4.0
码出高效,阿里巴巴JAVA开发手册1.4.0阅读笔记 一.编程规约(三) 代码格式// 关键词if与括号之间必须有一个空格,括号内的f与左括号,0与右括号不需要空格 if (flag == 0) { ...
- 【阿里巴巴Java开发手册1.7.0(嵩山版)】编程规约&MySQL 数据库规约
阿里巴巴Java开发手册1.7.0(嵩山版) 一.编程规约 (一)命名风格 所有命名不得以下划线和$开始和结束. 所有命名不得以拼音或拼音英文混合. 类名使用UpperCamelCase风格. 方法名 ...
- 304902阿里巴巴Java开发手册1.4.0
转自官网 前言 <阿里巴巴Java开发手册>是阿里巴巴集团技术团队的集体智慧结晶和经验总结,经历了多次大规模一线实战的检验及不断完善,系统化地整理成册,回馈给广大开发者.现代软件行业的高速 ...
- 《阿里巴巴Java开发手册1.4.0》阅读总结与心得(一)
前言 下面是阿里对<阿里巴巴 Java 开发手册>(下称<手册>)的介绍: 凝聚了阿里集团很多同学的知识智慧和经验,这些经验甚至是用血淋淋的故障换来的,希望前车之鉴,后车之师, ...
- 《阿里巴巴Java开发手册1.4.0》阅读总结与心得(五)
笔者作为一名有数年工作经验的Java程序员,仔细研读了这份手册,觉得其是一份不可多得的好材料.阿里巴巴在发布时所说,“阿里巴巴集团推出的<阿里巴巴Java开发手册(正式版)>是阿里巴巴近万 ...
- 阿里巴巴 Java 开发手册 (十二)安全规约
1. [强制]隶属于用户个人的页面或者功能必须进行权限控制校验. 说明:防止没有做水平权限校验就可随意访问.修改.删除别人的数据,比如查看他人的私信 内容.修改他人的订单. 2. [强制]用户敏感数据 ...
随机推荐
- javascript中的几种遍历方法浅析
1. for...in 用于对数组或者对象的属性的可枚举属性进行循环操作.注意该对象来自原型链上的可枚举属性也会被循环.下面看例子 var arr = ["lee","h ...
- iOS UITableViewCell点击时子视图背景透明的解决方法
在做iOS项目的开发中,UITableView控件的应用十分广泛.在进行自定义UITableViewCell时,经常遇到这样的问题:在UITableViewCell上面添加了一个有背景颜色的子视图,当 ...
- npm详解
一.npm介绍及安装 对于npm,大家多多少少都用过,作为一门技术,我想写篇博客记录一下,一起分享,一起学习. npm,是Node Package Manager的缩写,node的模块管理器,它是随同 ...
- IIS环境下部署项目
1.环境部署 1.1安装IIS7 进入控制面板,选择"程序和功能",进入如下页面后,点击"Turn Windows features on or off". 找 ...
- iOS·UIKit & Foundation框架—Annotations & Category注解工具类
- Java匿名内部类使用与示例
首先说为什么有匿名类 两个原因(产生的使命) 1.简化代码编写 某种情况下,类只需要扩展一个方法,没必要为了一个方法单独去写一个子类,然后然后调用子类,此时需要匿名类 2.在不同的包内的类内调用类的p ...
- stl_container容器和std_algorithm算法相同的函数
八.算法和容器中存在的功能相同的函数: 8.1.array: 8.1.1.fill. 1.在array中:void fill (const value_type& val); 2.在algor ...
- 实用收藏Linux命令备忘
系统操作 #使用shutdown命令马上重启系统[root@H32 ~]# shutdown –r now #使用shutdown命令马上关闭系统[root@H32 ~]# shutdown –h n ...
- Arcgis Engine OMD
在UML 图中有三种类型的类:抽象类(abstract class).组件类(COclass)与普通类(instantiable class). 抽象类:不能创建或实例化,从来没有一个抽象类的实例用于 ...
- OC分类(Category)
Category 分类 ,又称为类别.类目 概念 Category有多种翻译:分类.类别.类目(一般叫分类的多) Category式OC特有的语法,其他语言没有的语法(类似于C#语言中的"扩 ...