effective coding小结

本文总结了《Effective Coding》一书中的编码规范与最佳实践,包括命名风格、代码格式、OOP规约等方面,旨在提高代码的一致性、可读性和可维护性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

周六花了几个小时把effective coding这本小橙书看完了,主要讲的是编码过程中的一些习惯,希望我们能够形成规范,下面总结了一下。

很多编程方式客观上没有对错之分,一致性很重要,可读性很重要。过分随意的代码会影响到可扩展性以及可维护性。
不论是从性能,还是简洁优雅,都要具备‘精益求精’的工匠精神。
代码可维护性和算法效率     
个性化应尽量表现在系统架构和算法效率的提升上,而不是在合作规范上进行纠缠不休的讨论、争论、最后没有结论。

1.  编程规约
1.1 命名风格
(1)代码中的命名严禁使用拼音与英文混合的方法,避免歧义。注意,即使是纯拼音命名方式也要避免使用。
(2)类名使用UpperCamelCase风格。
(3)方法名、参数名、成员变量、局部变量都统一使用lowerCamelCase风格。
(4)常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长。
(5)抽象类命名使用Abstract或Base开头;异常类命名使用Exception结尾;测试类型以它要测试的类名开始,以Test结尾。
(6)包名统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词。包名统一使用单数形式,但是类型如果有复数含义,则类名可以使用复数形式。
(7)如果模块、接口、类、方法使用了设计模式,应在命名时提现出具体模式。
(8)接口类中的方法和属性不要加任何修饰符号,保持代码的简洁性,并加上有效的javadoc注释。尽量不要在接口里定义变量。
   
 各层命名规约:
 1)获取单个对象的方法用get作为前缀
 2)获取多个对象的方法用list作为前缀
 3)获取统计值的方法用count作为前缀
 4)插入方法用save/insert作为前缀
 5)删除的方法用remove/delete作为前缀
 6)修改的方法用update作为前缀
 
    (10)POJO是DO/DTO/BO/VO的统称,禁止命名成xxxPOJO 。

1.3 代码格式
     大括号的使用约定。如果大括号内为空,则简介地写成{}即可,不需要换行;如果是非空代码块,则:
     1)左大括号前不换行。
     2)左大括号后换行。
     3)右大括号前换行。
     4)右大括号后还有else等代码则不换行;表示终止的右括号后必须换行。
   
   (1) 左、右小括号和字符之间不出现空格。
    (2)if/for/while/switch/do等保留字与括号之间都必须加空格。
    (3)任何二目、三目运算符的左右两边都需要加一个空格。
    (4)注释的双斜线与注释内容之间有且仅有一个空格。
    (5)不同逻辑、不同语义、不同业务的代码之间插入一个空行分割开来,以提升可读性。
    (6)方法参数在定义和传入时,多个参数逗号后边必须加空格。

1.4 OOP规约

   (1) Object的equals方法容易抛空指针异常,应使用常量或确定有值得对象来调用equals。

   (2)POJO类必须写toString方法。在使用IDE中的工具生成toString时,如果继承了另一个POJO类,注意在前面加一下super.toString

    (3) 在循环体内,字符串的连接方式使用StringBuilder的append方法进行扩展。


1.5 集合处理
     (1)不要在foreach循环里进行元素的remove/add/操作。remove元素请使用Iterator方式,如果并发操作,需要对Iterator对象加锁。
      (2)使用entrySet遍历Map集合K/V,而不是用ketSet方式遍历。
     (3)利用Set元素唯一的特性,可以快速对一个集合进行去重操作,避免使用List的contains方法进行遍历、对比、去重操作。

1.6 并发处理
     (1)线程资源必须通过线程池提供,不允许在应用中自行显示创建线程。
     (2)线程池不允许使用Executors创建。而是通过ThreadPoolExecutor的方式创建,这样的处理方式能让编写代码的工程师更加明确线程池的运行规则,  避免资源耗尽的风险。
     (3)在并发修改同一记录时,为避免更新丢失,需要加锁。要么在应用层加锁,要么在缓存层加锁,要么在数据库层使用乐观锁,使用vresion作为更新依据。
     (4)如果每次访问冲突概率小于20%,推荐使用乐观锁,否则使用悲观锁。乐观锁的重试次数不得小于3次。

1.7 控制语句
     (1)在if/else/for /while / do语句中,必须使用大括号。即使只有一行代码,也应避免采用单行编码方式。
     (2)在高并发场景中,避免使用“等于”判断作为中断或退出的条件。
     (3)如果并发控制没有处理好,容易产生等值判断被“击穿”的情况,应使用大于或小于的区间判断条件来代替。
     ps:判断剩余奖品数量等于0时,终止发送奖品,但是因为并发处理错误导致奖品数量瞬间变成了负数,这样的话,活动无法终止。
     (4)除常用方法(如getXxx/isXxx)外,不要在条件判断中执行其他复杂的语句,可将复杂逻辑判断的结果赋值给一个有意义的布尔变量名,可提高可读性。

1.8 注释规约
     (1)类、类属性、类方法的注释必须使用Javadoc规范,使用/**内容*/格式,不得使用//xxx方式。
     (2)方法内部的单行注释,在被注释语句上方另起一行,使用//注释。方法内部的多行注释,使用/**/注释,注意与代码对齐。
     (3)语义清晰的代码不需要额外的注释。

1.9 其他
     (1)获取当前毫秒数用System.currentTimeMillis();而不是用new Date().getTime();
     (2)对于展示被注释掉,后续可能恢复使用的代码片段,在注释代码上方,统一规定使用三个斜杠(///)来说明注释掉代码的理由。

2.1 异常处理
     (1)避免出现重复的代码(Don't Repeat Yourself);
     (2)一个类中有多个public方法,都需要进行数行相同的参数校验操作,这个时候请抽取:
     private boolean checkParam(DTO dto){...}
     (3)如果非必要,请不要打出error级别的日志,error级别只记录系统逻辑出错、异常等重要的错误信息。

3 单元测试
     (1)单元测试应该是全自动执行的,并且是非交互式的。测试用例通常是被定期执行的,执行过程必须完全自动化才有意义。需要人工检查输出结果的测试不是一个好的单元测试。单元测试中不准使用System.out进行人肉验证,必须使用assert验证。
      (2)对于单元测试,要保证测试粒度够小,有助于精确定位问题。单元测试粒度至多是类级别,一般是方法级别。
      (3)单元测试代码必须写在如下工程目录下:src/test/java,不允许写在业务代码目录下。

      编写单元测试代码应遵循BCDE原则,以保证被测试模块的交付质量。
     1 ) B:Border,边界值测试,包括循环边界、特殊取值、特殊时间点、数据顺序等。
     2 ) C:Correct,正确的输入,并得到预期的结果。
     3 )    D:Design,与设计文档相结合,来编写单元测试。
     4 ) E:Error,强制错误信息输入,并得到预期的结果 。

5 MySQL数据库
     (1)表达是与否概念的字段,必须使用is_xxx的方式命名,数据类型是unsigned tinyint(1表示是,0表示否)
     (2)MySQL在windows下不区分大小写,但在Linux下默认区分大小写。
     (3)表名不适用复数单词。
     (4)varchar是可变长字符串,不预先分配存储空间,长度不要超过5000个字符。如果存储长度大于此值,则应定义字段类型为text,单独出来一张表,用主键来对应,避免影响其他字段的索引效率。
     (5)MySQL并不是跳过offset行,而是取offset+N行,然后返回放弃前offset行,返回N行。
     (6)不要使用count(列名)或count(常量)来代替count(*);
     (7)count(*)会统计值为NULL的行,而count(列名)不会统计此列为NULL值的行。
     (8)当某列的值全为NULL时,count(col)的返回结果为0,但sum(col)的返回结果为NULL,因此使用sum()时需要注意NPE问题。
     (9)可以使用如下方式来避免sum的NPE问题:select if(isnull(sum(g))0,sum(g)) from table;
     (10)不得使用外键与级联,一切外键概念必须在应用层解决。
     (11)禁止使用存储过程,存储过程难以调试和扩展,更没有移植性。
     (12)in操作能避免则避免,若实在避免不了,需要评估in后面的集合元素数量,控制在1000个以内。

5.4 ORM映射
     (1)在表查询中,一律不要使用 * 作为查询的字段列表,需要哪些字段必须明确写明。  
     分层领域模型规约:
     1)DO(Data Object):与数据库表结构一一对应,通过DAO层向上传输数据源对象。
     2)DTO(Data Transfer Object):数据传输对象,Service或Manager向外传输的对象。
     3)BO(Business Object):业务对象。由Service层输出的封装业务逻辑的对象。
     4)AO(Application Object):应用对象。在Web层与Service层之间抽象的复用对象模型,极为贴近展示层,复用度不高。
     5)VO:(View Object):显示层对象,通常是Web向模板渲染引擎层传输的对象。
      6)Query:数据查询对象,各层接收上层的查询请求。如果是超过2个参数的查询封装,则禁止使用Map类来传输。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值