代码规范_代码规范化 - CSDN
精华内容
参与话题
  • 程序员必须要注意的代码规范

    千次阅读 2014-12-04 09:56:38
    您是否有因代码杂乱冗余而心生厌恶,您是否有过因代码晦涩难懂而抓狂,您是因代码低级的逻辑错误而愤概,您是否因代码结构不合常规而需要到处查找,您是否因看到几百甚至上千行代码的方法而望洋兴叹,您是否因代码...

    作为一个苦逼的程序员,因为种种原因经常需要阅读别人写的代码。您是否有因代码杂乱冗余而心生厌恶,您是否有过因代码晦涩难懂而抓狂,您是因代码低级的逻辑错误而愤概,您是否因代码结构不合常规而需要到处查找,您是否因看到几百甚至上千行代码的方法而望洋兴叹,您是否因代码缺少注释而猜测以及花很多时间去理清楚前后逻辑。苦逼的我全部遇到过并且很多很多,这些代码的作者从世界500强顶级IT公司到几十人的小公司同事,从印度美国新加坡人到中国人,从七八年的老人到刚入行的菜鸟。相信您也遇到过。这些人有一些共性,应付任务,个性十足以及不思进取!如果您是程序员菜鸟,那么您一定遇到很多并且既是肇事者又是受害者,这是必经之路;如果你是业界大牛,不用说您眼里别人的代码都或多或少都有问题,遇到的情况更多!

    都说代码是程序员的第二张脸,写了太烂的代码背后一定会遭人鄙视。请遵循一些简单的规范,写干净一致的代码!请把您的个性用在写出最简单易懂的代码上面,而不是晦涩冗余无用的代码,甚至自我签名!您的才华应该表现在设计良好的结构和模式,表现在干净易懂的代码,表现在对空间的尊重,对代码的尊重。这样您才能赢得别人的尊重!请记住代码不是一次性的,需要重复的修改和重构,为未来写点代码!以下我总结几点Java里面最基本的小规范:

    1.  写干净整洁的代码,请尊重空间,请尊重人眼的偏好

    1.1  去除没有用到的类引用,eclipse里面Ctrl+Shilft+O。看到一大片的因为类引用没有用到而报的警告信息简直就是灾难,空间和视觉都没有得到尊重。

    1.2  记得格式化代码,eclipse里面Ctrl+Shilft+F。看到一大片杂论无章,连基本的对齐都没有的代码也是很大的灾难,视觉脑力都会受到挑战。

    1.3  不要吝惜废弃的老代码,eclipse里面Ctrl+D。有些人对待已经废弃的老代码比对待自己的老婆还宝贝,大量运用注释来保留,随 着代码的演变暂用非常大量的空间。如果那段代码非常精妙,舍不得删,那么请把它移到您的私人代码库。

    1.4  请不要写冗余无用的代码。if(true)之类的代码块完全不应该出现,用空行隔开该段代码是更好的选择。

    1.5  请合理运用空行。空行可以用来隔开相对独立的代码块,有利于阅读和理解。但是不要使用超过一行的空行,对空间,别太奢侈了。

    1.6  请不要在两个地方出现完全相同的代码,您总是可以想办法重用的,不是吗?

    1.7 命名类,方法,变量慎用简写,除非大家都公认。全称我都不一定看得懂,简称您太高估我的智商了!请问qrbs代表什么,可能火星人知道吧!

    1.8 把所有的类变量放到最前面,如果比较多请按用途分组排列,不要把变量散落在大江南北,我找的真的很辛苦!

    1.9  拆分大的类,大的方法,如果您的类有一万行,如果您的方法有一千行,我真的会恐惧,是恐惧!

    2.  高效运用注释

    2.1  规范的注释类信息。请查看一下Java标准库的String.java源码吧,包括文件名,日期,作者,版本号等信息,用统一的模板。千 万别把您的大名散落于方法签名甚至于具体代码里面了。我在读业务逻辑的时候没有兴趣思考您的人生!要找您我可以在类签名里面找到的,放心啊!

    2.2  非Java Bean的public方法都需要注释,您总不会要别人读您的代码才能调用您的代码吧!即便您的英文非常好,命名也非常规范,您总不能期待别人都英文好,理解都一样吧。

    2.3  为不容易理解类变量注释。类变量特别是私有的类变量没有人要求注释,但是为了能够快速的了解您表示的是什么,还是写点什么吧!您知道我英文不算好!

    2.4  注释代码段,注释逻辑选择。上面提到运用空行分割开逻辑相对独立的代码,那么请在空行的下一行也写点下面代码段要干什么的语句吧。 如果有if else等逻辑选择的时候,麻烦也花几秒钟写上判断的依据和结果好吗?逻辑难懂且关键,您懂的!

    3. 不断学习,不断思考,不断实践,更上一层楼

    3.1 遇到不懂的,请先google,一定要学会,不然就一直不会了,回头发现工作六七年没有工作两年的小朋友懂的多!

    3.2 看别人代码时要汲取好的方法和技巧。

    3.3 接触一项技术要升入了解和实践,请问您做过的系统您现在都可以从零开始搭建起来了吗,我的意思是架构搭建哦!

    3.4 书里面有知识,有思想,有时间的话还是多精读几本经典书籍吧。您会受益匪浅!


    以上只是一点个人的想法,您可以接受或者反驳。谢谢您的时间,就这样!

    展开全文
  • 代码规范】常见编码规范

    万次阅读 2018-06-26 16:27:31
    如果一个功能将在多处实现,即使只有两行代码,也应该编写方法实现。说明:虽然为仅用一两行就可完成的功能去编方法好象没有必要,但用方法可使功能明确化,增加程序可读性,亦可方便维护、测试。 2.应明确规定对...

    文章来源:公众号-智能化IT系统。


    1.明确方法功能,精确(而不是近似)地实现方法设计。如果一个功能将在多处实现,即使只有两行代码,也应该编写方法实现。

    说明:

    虽然为仅用一两行就可完成的功能去编方法好象没有必要,但用方法可使功能明确化,增加程序可读性,亦可方便维护、测试。

     

    2.应明确规定对接口方法参数的合法性检查应由方法的调用者负责还是由接口方法本身负责,缺省是由方法调用者负责。

    说明:

    对于模块间接口方法的参数的合法性检查这一问题,往往有两个极端现象,即:要么是调用者和被调用者对参数均不作合法性检查,结果就遗漏了合法性检查这一必要的处理过程,造成问题隐患;要么就是调用者和被调用者均对参数进行合法性检查,这种情况虽不会造成问题,但产生了冗余代码,降低了效率。

     

    3.明确类的功能,精确(而不是近似)地实现类的设计。一个类仅实现一组相近的功能。说明:划分类的时候,应该尽量把逻辑处理、数据和显示分离,实现类功能的单一性。

    示例:

    数据类不能包含数据处理的逻辑。通信类不能包含显示处理的逻辑。

     

    4.所有的数据类必须重载toString() 方法,返回该类有意义的内容。说明:父类如果实现了比较合理的toString() , 子类可以继承不必再重写。

    示例:

    public TopoNode
     {
         private String nodeName;
         public String toString()
          {
             return "NodeName : " +  nodeName;
          }
     }

     

    5.数据库操作、IO操作等需要使用结束close()的对象必须在try -catch-finally finallyclose()


    6.异常捕获后,如果不对该异常进行处理,则应该记录日志(针对后台)。

    说明:若有特殊原因必须用注释加以说明。


    7.自己抛出的异常必须要填写详细的描述信息。

    说明:便于问题定位。

    示例:

    throw  new IOException("Writing data error! Data: " + data.toString());

     

    8. 在程序中使用异常处理还是使用错误返回码处理,根据是否有利于程序结构来确定,并且异常和错误码不应该混合使用,推荐使用异常。说明:一个系统或者模块应该统一规划异常类型和返回码的含义。但是不能用异常来做一般流程处理的方式,不要过多地使用异常,异常的处理效率比条件分支低,而且异常的跳转流程难以预测。

     

    9.避免使用不易理解的数字,用有意义的标识来替代。涉及物理状态或者含有物理意义的常量,不应直接使用数字,必须用有意义的静态变量来代替。
    示例:

    如下的程序可读性差

    if  (state == 0)

    {

    state = 1;

    ... // program  code

    }

    应改为如下形式

    private final static int  TRUNK_IDLE = 0;
     private final static int TRUNK_BUSY = 1;
     private final static int TRUNK_UNKNOWN = -1;
     
     

    if (state == TRUNK_IDLE)

    {
         state = TRUNK_BUSY;
         ... // program code

    }

     

    10.数组声明的时候使用 int[] index ,而不要使用 int index[] 。说明:

     

    11.异常捕获尽量不要直接 catch (Exception ex) ,应该把异常细分处理。


    12.不要使用难懂的技巧性很高的语句,除非很有必要时。说明:高技巧语句不等于高效率的程序,实际上程序的效率关键在于算法。


    公众号-智能化IT系统。每周都有技术文章推送,包括原创技术干货,以及技术工作的心得分享。扫描下方关注。



    公众号-智能化IT系统。每周都有技术文章推送,包括原创技术干货,以及技术工作的心得分享。扫描下方关注。

    展开全文
  • 解读阿里官方代码规范

    千次阅读 2017-12-27 15:30:54
    2017年开春,阿里对外公布了「阿里巴巴Java开发手册」。作为一个13年经验的码农,从头到尾浏览了一遍这份手册之后,感觉很棒。虽然其中的某些观点笔者不能...笔者将对这份代码规范中的一些细节做一些解读,包含笔者

    转载来源:https://www.cnblogs.com/winner-0715/p/7594254.html

    2017年开春,阿里对外公布了「阿里巴巴Java开发手册」。作为一个13年经验的码农,从头到尾浏览了一遍这份手册之后,感觉很棒。虽然其中的某些观点笔者不能苟同,但大部分的规范还是值得绝大多数程序员学习和遵守的。

    笔者将对这份代码规范中的一些细节做一些解读,包含笔者的观点和想法,可以作为这份代码规范的扩展阅读。对于规范中某些「显而易见」的条款,将不在解读范围之列(换言之,这都不懂,就说明你天赋不够,乘早别做程序员了)。

    当然,笔者在日常的编程过程中属于「代码洁癖偏执狂」,所以文中的某些观点仅代表个人看法,请勿人生攻击。

    阿里官方代码规范解读系列总计五篇,已在本公众号发过,本篇为合集,对之前文章中的部分内容作了修订。

    命名规约

    1.1.1 代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束
    
    1.1.2 代码中的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式
    
    1.1.3 / 1.1.4 类名使用UpperCamelCase风格,必须遵从驼峰形式(某些情况诸如领域模型相关的命名除外);方法名、参数名、成员变量、局部变量都统一使用lowerCamelCase风格,必须遵从驼峰形式
    
    1.1.5 常量命名全部大写,单词间用下划线隔开
    
    1.1.9 包名统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词

    上述规则,主要是规定了你书写Java的时候,哪些字符可以用,什么时候用大写,什么时候用小写。应该说,绝大多数写Java的都遵循着上述的规范,就像笔者说的:尼玛这都不懂,乘早改行别写Java了。

    笔者在实际编程过程中,对类名的风格,可能更激进一些,根据阿里的规范:

    类名使用UpperCamelCase风格,必须遵从驼峰形式,但以下情形例外:(领域模型的相关命名)DO / BO / DTO / VO等

    实际上还是有可能会存在着诸如:UserVO,UserDTO,UserDAO这样的命名。对不起,在笔者的团队中,这样的命名也会被禁止,这里分为2种情况:

    禁止使用 VO / BO / DTO / VO 等进行领域模型的命名

    有读者要问,那么如果万一项目中要使用DTO或者VO咋办?笔者的观点如下:

    第一,项目中避免使用DTO或者VO,DTO是一个早在2004年就被讨论并认定为一个反模式的东西;

    第二,谁规定领域模型就一定要用DTO或者VO做结尾?还原领域模型的本来意义才是命名的核心,一个User在实际业务系统中可能是一个Admin或者Supervisor,那就直接用Admin来命名,而不是把User转化成UserVO,UserVO啥都不是,是初级程序员造出来的一个怪胎。

    所有的DAO使用正常的驼峰法进行命名,例如:UserDao

    对上面这条,或许有很多DAO大写党要发飙了。其实笔者就想反问这些人一句:你咋不把UserService写成UserSERVICE呢?

    命名原则

    1.1.5 力求语义表达完整清楚,不要嫌名字长
    
    1.1.10 杜绝完全不规范的缩写,避免望文不知义

    这两条说的是命名的基本原则,总的来说其实表达了一个意思:你他妈的别给我用缩写!

    其实有很多程序员会非常神奇的患上「缩写综合症」。比如非常典型的就是:UserMgmt,这他妈是什么鬼?多敲几个字母会死么?

    类的命名

    1.1.6 抽象类命名使用Abstract或Base开头;异常类命名使用Exception结尾;测试类命名以它要测试的类的名称开始,以Test结尾
    
    1.1.13 对于Service和DAO类,基于SOA的理念,暴露出来的服务一定是接口,内部的实现类用Impl的后缀与接口区别
    
    1.1.13 如果是形容能力的接口名称,取对应的形容词做接口名
    
    1.1.14 枚举类名建议带上Enum后缀,枚举成员名称需要全大写,单词间用下划线隔开
    
    1.1.11 如果使用到了设计模式,建议在类名中体现出具体模式
    
    1.1.9 包名统一使用单数形式;类名如果有复数含义,类名可以使用复数形式

    上述规则,主要在讲述具体命名一个类的时候的一个「用词规范」。这些用词规范绝大多数实际上也是一种约定俗成,比如Abstract前缀,Exception后缀等等。

    对于接口的命名,笔者最为不能忍受的一种命名,就是将所有的接口以大写字母I开头,诸如:IUserService。真是一种坑爹到极致的命名:第一,IUserService纠结是一个啥玩意儿?好好的UserService,加上一个大写字母I,直接失去了阅读时的语义性;第二,谁他妈知道你这东西到底是大写字母I还是数字1啊?

    有关枚举类名是否加上Enum后缀,笔者对此有所保留。在笔者的团队中,是不使用Enum作为后缀的,但对此并不反感。至于枚举成员名称,不用大写字母并下划线隔开的,基本属于缺心眼行为。Enum的设计初衷就是对常量的规整和扩展,所以命名规范继承自常量是比较合理的一种选择。

    在命名中体现设计模式,相信这一点很多程序员都能遵守。因为在笔者看来,能在代码中熟练使用设计模式的同学,通常也不会是一个对自己毫无要求的烂货。这条命名规范在Spring以及很多优秀的开源项目中都有很深刻的体现。

    类名是否可以使用复数形式,相信主要的分歧来自于工具类。笔者的规定是:

    提供一系列静态方法的工具类,一概使用Utils作为后缀命名

    这条规范的依据,主要来自于笔者发现commons和spring这两个比较优秀的开源框架中提供的工具类通常都带s结尾。

    常量规约

    
    1.2.3 不要使用一个常量类维护所有常量,应该按常量功能进行归类,分开维护
    
    1.2.4 常量的复用层次有五层:跨应用共享常量、应用内共享常量、子工程内共享常量、包内共享常量、类内共享常量
    
    1.2.5 如果变量值仅在一个范围内变化用Enum类。如果还带有名称之外的延伸属性,必须使用Enum类
    
    1.1.12 尽量不要在接口里定义变量,如果一定要定义变量,肯定是与接口方法相关,并且是整个应用的基础常量

    常量规约的核心有两点:第一,别使用常量;第二,让常量可控。

    常量的存在按照笔者个人的理解是向下兼容的选择(因为JDK1.5之后才出现枚举)外加用起来足够爽(想象一下静态调用时引用的便捷性,甚至基本类型可以直接参与业务逻辑的计算)。

    所以在上述规则中,我们可以看到常量进化到枚举的趋势,也能看到由于用起来足够爽带来的常量管理需求:要求分组(1.2.3)以及要求放在合适的位置(1.2.4)。

    有关分组,笔者有不同意见:常量分组未必要分散到不同的类,在一个常量类中定义静态类也是一种分组方式,有时候这样的分组方式可能管理起来更有效。

    至于接口中只能定义常量不能定义变量,基本就属于幼儿园规则了。

    语法糖

    
    1.1.12 接口类中的方法和属性不要加任何修饰符号(public 也不要加),保持代码的简洁性,并加上有效的Javadoc注释
    
    1.4.2 所有的覆写方法,必须加@Override注解
    
    1.4.3 可变参数必须放置在参数列表的最后。(提倡同学们尽量不用可变参数编程)
    
    1.4.4 对外暴露的接口签名,原则上不允许修改方法签名,避免对接口调用方产生影响。接口过时必须加@Deprecated注解,并清晰地说明采用的新接口或者新服务是什么
    
    1.4.5 不能使用过时的类或方法
    
    1.4.10 序列化类新增属性时,请不要修改serialVersionUID字段,避免反序列失败
    
    1.4.17 循环体内,字符串的联接方式,使用StringBuilder的append
    
    1.4.18 final可提高程序响应效率
    
    1.4.19 慎用Object的clone方法来拷贝对象

    有关语法糖的总结其实比较牵强,因为绝大多数的规则看上去都比较小儿科,比如像覆写方法的@Override注解,@Deprecated注解,可变参数的问题等等基本上都在IDE层面解决了。

    当一个项目在IDE中产生了一些由于使用过时方法之类的事儿导致的warning时,有洁癖的程序员应该主动修复这个warning。这也是是一个程序员的基本素养问题。

    最后的三条,笔者认为有点鸡肋,对于初级程序员,大多还到不了考虑final和clone的层次;而中高级程序员,这几条规则对他们而言并无问题。

    基本类型

    
    1.4.7 所有的相同类型的包装类对象之间值的比较,全部使用equals方法比较
    
    1.4.8 所有的POJO类属性必须使用包装数据类型
    
    1.4.8 RPC方法的返回值和参数必须使用包装数据类型
    
    1.4.8 所有的局部变量【推荐】使用基本数据类型

    有关基本类型的声明(1.2.2)和比较(1.4.7),这两条规则比较直观,不再叙述。

    而有关基本类型和包装类型的使用,这东西一直是吵架的核心。用还是不用?这是个问题!很显然,阿里同学的观点是:为了提高程序的容错性和扩展性,尽可能使用包装类型。

    从阿里同学举的例子来说,也是有一定说服力的:

    数据库的查询结果可能是null,因为自动拆箱,用基本数据类型接收有NPE风险
    
    比如显示成交总额涨跌情况,即正负x%,x为基本数据类型,调用的RPC服务,调用不成功时,返回的是默认值,页面显示:0%,这是不合理的,应该显示成中划线-。
    所以包装数据类型的null值,能够表示额外的信息

    不过笔者认为,如果程序员对程序能够驾驭得比较好,基本类型也是一种很好的选择。因为基本类型有一些比较好用的特性:比如说默认值。笔者在这里也举个例子进行说明:

    通常我们都会用is_disabled字段在数据库中表示某一个表的记录是否被逻辑删除,而这个字段,在Java代码中被映射成什么类型呢?
    
    Boolean?如果被映射成包装类型,那么数据库里面的这个字段就可以为null,有些读者会说,这并没有什么问题啊。可是,数据库is_disabled字段如果为null,代表什么逻辑含义呢?
    这条记录究竟是有效还是无效? 如果这个字段不能为null,那么将其映射成基本类型是一个皆大欢喜的事情:既保证了数据库数据的完整性,我们在初始化的时候还可以忽略这个字段,因为boolean天生的默认值就是false

    所以,笔者对于包装类还是基本类型的结论是:

    一切跟着业务的实际情况而定,基本类型也有其生存空间

    方法命名

     - 获取单个对象的方法用get做前缀
     - 获取多个对象的方法用list做前缀
     - 获取统计值的方法用count做前缀
     - 插入的方法用save(推荐)或insert做前缀
     - 删除的方法用remove(推荐)或delete做前缀
     - 修改的方法用update做前缀

    有关方法的命名,笔者想多说几句不同意见。对于上述的规则,笔者认为适合在DAO这个层次进行实践,而不能应用于Service层。

    使用Hibernate作为持久层框架的读者,对Hibernate的API应该比较熟悉,而上面的命名规范,和Hibernate对外暴露的API名称是很接近的。我们知道,通常到了DAO这个层次,数据库操作相对来说是一个原子操作,所以增删改查的语义是最适合做方法命名的。这也就是笔者认为这套规则在DAO层能够被实践得很好的一个原因。

    当然,上述规则中有一个例外:

    获取单个对象用load做前缀,避免使用get

    原因很简单,get可能是getter方法的前缀,作为一个偏执狂,老子不冒风险。

    话题回到Service的命名上来,为什么笔者不认同使用相同的命名规范作用于Service层呢?因为Service层通常是对外暴露的接口,具有一定的业务意义,也就是说Service层通常也不会是简单的增删改查,而是若干原子操作的集合。

    举两个很简单的例子:发短信。发短信这个业务中可能包含了本地配置的读取、本地数据库的读写,远程服务的调用。我们可以看到这是一连串数据库操作甚至是异构系统调用的集合实现,能用简单的增删改查来命名吗?所以,笔者的观点很简单:

    Service层接口方法的命名,应还原业务的本来面目,采用动词或者动宾结构来进行方法的命名

    举例来说:resetPassword / login / sendMessage 都是比较合理的命名方式。

    方法和属性

    
    1.4.11 构造方法里面禁止加入任何业务逻辑,如果有初始化逻辑,请放在init方法中
    
    1.4.14 当一个类有多个构造方法,或者多个同名方法,这些方法应该按顺序放置在一起,便于阅读
    
    1.4.15 类内方法定义顺序依次是:公有方法或保护方法 > 私有方法 > getter/setter方法
    
    1.4.16 setter方法中,参数名称与类成员变量名称一致,this.成员名=参数名。在getter/setter方法中,尽量不要增加业务逻辑
    
    1.4.20 类成员与方法访问控制从严

    这几条规约理解起来不难,执行起来也不难。要探究背后的原因,可能就需要花点功夫。

    比如,构造方法和setter/getter方法禁止加入业务逻辑,主要是这些方法有很大概率被程序框架的反射机制调用。一旦其中含有业务逻辑,那么调试和定位就会变成灾难

    不过对于getter方法,通常要网开一面。因为在实际情况中,我们往往会在一个POJO中加入额外的getter方法用于序列化或者内部逻辑的使用。在这种情况下,避免和其他getter方法产生分歧是需要注意的地方。

    至于说到类内的方法定义顺序,笔者基本同意上述规则,但在实际执行中可能更加严格:getter和setter方法的顺序也有严格讲究,必须是先getter方法,后setter方法,而不是让它们成对出现。

    有关类成员和方法的访问控制,阿里的同学洋洋洒洒说了好几条,语法层面偏多,在这里就不再详细展开。

    格式规约

    格式规约是代码规范中争议最大的,由于条目众多,在这里就不逐一解读,挑选几条大致说一下。

    
    1.3 6. 单行字符数限不超过 1201.3.8 IDE的text file encoding设置为UTF-8; IDE中文件的换行符使用Unix格式,不要使用windows格式
    
    1.3.10 方法体内的执行语句组、变量的定义语句组、不同的业务逻辑之间或者不同的语义之间插入一个空行

    绝大多数情况下,空格党和Tab党的较量是空格党完胜。笔者也不记得是多少年前被一位前辈教育说禁止使用Tab,就保持了良好的习惯至今。对于缩进,个人比较赞同4个空格,但HTML等页面上使用4个空格的话,一些复杂页面的缩进就会比较恐怖,此时可以降级为2个空格。

    对于单行字符数的限制不超过120个这条规则,笔者完全不能认同。这里面牵涉到的情况比较多,不能一棒子打死了。有些逻辑有大量的分支和循环的嵌套,如果遵循4个空格的缩进原则,碰到方法名称还比较长的状况,就要折行,这给代码阅读带来极大的困扰;另外有一种情况,就是需要额外进行比较长的注释编写,不能写在一行里的感觉真是比较糟糕,因为还得考虑断句才不影响阅读。另外,笔者有一个习惯是在条件语句边上加一句注释,这样就有很大概率会超出120字:

    有人会问,条件语句边上加注释是什么鬼?从上面的代码上可以看到,条件语句上面的一行注释实际上在解释整个代码片段,而条件语句边上的注释说明的是条件语句本身!当然如果读者有更好的写注释的位置,请及时给笔者留言。

    文件的UTF-8和Unix格式没什么好说的,IDE支持的也很好。但这一点对初级程序员尤为重要,我已经不知道多少次就这个问题惩罚过实习生了。

    有关语句组空行,是笔者极力推荐的一个做法。这不仅仅是为了空行而空行,这里的空行本身就是一种编程思路的整理。而笔者还有一个习惯就是对比较复杂的逻辑,都在语句组的前面加上注释,注释也用编号编排,这样回头debug时也会极大提升效率。

    集合类型

    阿里规范中的集合类型这个章节,感觉写得比较鸡肋。绝大多数的规范似乎都是针对初级程序员的。笔者看了半天也没总结出一条值得额外解读的,所以权当复习一遍基础知识就好。

    并发处理

    
    1.6.2 创建线程或线程池时请指定有意义的线程名称,方便出错时回溯
    
    1.6.3 线程资源必须通过线程池提供,不允许在应用中自行显式创建线程
    
    1.6.4 线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor去创建

    上面这4条规则主要是针对线程的创建和使用。由于Spring的存在,其实上述情况不太可能发生。

    1.6.5 高并发时,同步调用应该去考量锁的性能损耗。能用无锁数据结构,就不要用锁;能锁区块,就不要锁整个方法体;能用对象锁,就不要用类锁
    
    1.6.7 对多个资源、数据库表、对象同时加锁时,需要保持一致的加锁顺序,否则可能会造成死锁
    
    1.6.8 并发修改同一记录时,避免更新丢失,要么在应用层加锁,要么在缓存加锁,要么在数据库层使用乐观锁,使用version作为更新依据

    上面这3条规则主要是针对锁。不过这几条规则看上去更像是3道面试题的答案。这3道面试题分别是:

    使用锁同步,有什么需要注意的地方?
    
    什么是死锁?举例说明什么情况会发生死锁?
    
    什么是乐观锁?什么是悲观锁?分别用在什么场景?

    相信能解答上述面试题的同学,应该对上面的原则了然于心。

    
    1.6.10 使用CountDownLatch进行异步转同步操作,每个线程退出前必须调用countDown方法,线程执行代码注意catch异常,确保countDown方法可以执行,
    避免主线程无法执行至countDown方法,直到超时才返回结果回溯
    1.6.13 volatile解决多线程内存不可见问题。对于一写多读,是可以解决变量同步问题,但是如果多写,同样无法解决线程安全问题 1.6.14 HashMap在容量不够进行resize时由于高并发可能出现死链 1.6.15 ThreadLocal无法解决共享对象的更新问题,ThreadLocal对象建议使用static修饰。这个变量是针对一个线程内所有操作共有的,所以设置为静态变量,

    所有此类实例共享此静态变量

    上面这些规则基本上属于知识贴范畴,可以一带而过,有些可能不太会实际碰到。像定时任务,可能使用Spring的封装更多一些,而Spring默认就是使用ScheduledExecutorService的。

    而CountDownLatch的异常捕获,也是一个老生常谈的问题了,属于多线程编程的基本功。

    最后的三条对于写应用的同学接触不多,但写底层的同学应该会很熟悉。

    注释规约

    注释规约的内容比较多,这里也仅挑选一些具有代表性的进行解读 

    
    1.8.6 与其"半吊子"英文来注释,不如用中文注释把问题说清楚。专有名词与关键字保持英文原文即可
    
    1.8.8 注释掉的代码尽量要配合说明,而不是简单的注释掉
    
    1.8.10 好的命名、代码结构是自解释的,注释力求精简准确、表达到位

    枚举类加注释是非常必要的,因为枚举通常是都是常量的扩展,而常量是需要说明的。

    鉴于很多程序员的英语水平,笔者建议英语不够好的程序员直接使用中文写注释。

    对于注释掉的代码,笔者的意见是在绝大多数情况下应该直接删除,除非在很短的时间内还有恢复的余地。

    有关什么是好的命名和代码结构,什么样的命名能够使得代码做到自解释,笔者将另外撰文进行说明。

    数据库规约

    数据库规约本身并不属于Java规约的范畴,不过阿里的规范中包含了不少数据库规约的内容,所以笔者也同样加以解读。

    
    3.1 2 表名、字段名必须使用小写字母或数字;禁止出现数字开头,禁止两个下划线中间只出现数字
    
    3.1.3 表名不使用复数名词
    
    3.1.4 禁用保留字
    
    3.1.5 唯一索引名为uk_字段名;普通索引名则为idx_字段名
    
    3.1.10 表的命名最好是加上业务名称_表的作用
    
    3.1.11 库名与应用名称尽量一致

    上述规约主要说的是库、表、字段的命名规约。应该说绝大多数的上述规约都是参考项,需要根据实际情况进行调整,我们逐条来说。

    有关布尔值的数据库映射,对于使用is_xx进行命名没有异议,对于数据类型是否应该使用tinyint稍有保留,笔者实际上使用bit更多。由于布尔值所对应的Java类型是boolean,所以笔者通常在命名时,利用boolean的默认值特性,对一些常用的命名进行更加严格的规定。比如「是否有效」,命名成为「is_disabled」就要比「is_enabled」来的好。因为 is_disable = false 是绝大多数程序的事实逻辑,这样就可以利用boolean值默认为false的特性。

    Java中的绝大多数命名都使用驼峰法,而数据库的命名实际上更加严格。光光小写是不够的,而是要强制使用下划线命名法(主要是因为SQL是大小写不敏感的语言)。笔者在实际工作中经常看到使用驼峰法命名表名或者字段名的,这种基本上属于小学没毕业的行为。

    有关表名不能使用复数,不能使用关键字,这些属于比较基础的命名规范,应该遵守。但是笔者在这里提出更为严格的要求:不仅不能使用SQL关键字进行命名,同样不允许使用Java关键字!因为绝大多数情况,数据库字段会被映射到相应的Java对象,如果可以使用Java关键字,那么映射的时候就是自找麻烦了。

    最后三条规约属于建议,相信每个公司都有自己独特的规定。比如笔者见过有一些写Oracle出身的程序员,习惯使用tbl_做表名的前缀,使用vw_做视图的前缀。个人觉得这个方面不宜做过多规定,只要团队保持风格整体一致即可。

    3.1.6 小数类型为decimal,禁止使用float和double
    
    3.1.7 如果存储的字符串长度几乎相等,使用char定长字符串类型
    
    3.1.8 varchar是可变长字符串,不预先分配存储空间,长度不要超过5000

    这三条主要说的是数据库设计时的类型规约。

    除了上述三条之外,在笔者团队另外还会遵守如下几条:

    明确日期和时间,日期使用date类型并使用xxDate进行Java字段命名,时间使用date_time类型并使用xxTime进行Java字段命名,以示区分

    上面这条主要是和日期时间有关的,强制这样的规约,对于提升代码的可读性是有帮助的。

    枚举类型在数据库中既可以映射成int,也可以映射成varchar,视实际情况定

    通常对于排序和检索有强依赖的,枚举类型映射成int比较理想,否则可以映射成varchar。虽然从效率上说,int基本上会强于varchar,但varchar毕竟可读性更好,所以还是应该一分为二来看。

    
    3.1.8 如果存储长度大于此值,定义字段类型为text,独立出来一张表,用主键来对应,避免影响其它字段索引效率
    
    3.1.12 如果修改字段含义或对字段表示的状态追加时,需要及时更新字段注释
    
    3.1.13 字段允许适当冗余,以提高性能,但是必须考虑数据同步的情况
    
    3.1.14 单表行数超过500万行或者单表容量超过2GB,才推荐进行分库分表
    
    3.1.15 合适的字符存储长度,不但节约数据库表空间、节约索引存储,更重要的是提升检索速度

    上面的规约主要涉及到一些数据库表设计上的原则。

    其中,3.1.8是非常值得大家注意的一点,笔者个人的习惯是对于大字段,拆表的同时,优化SQL,尽可能做到用主键单独取大字段,避免产生效率瓶颈。

    而3.1.14是希望提醒一些自视甚高的架构师不要过早的进行过度设计。这里笔者提一点:

    对于每一张数据库表的设计,应该预估表在未来若干时间段内的数量,以采取最佳的程序处理措施

    这里所说的最佳程序处理措施包括并不限于:使用应用级别缓存对数据库进行减压;选取合适的时间点对表进行分库分表;是否进行人为拆表以保证较快的SQL执行等等。

    有关3.1.13,我们在有关SQL编写环节还会说到。

    
    3.2.2 超过三个表禁止join
    
    3.2.3 在varchar字段上建立索引时,必须指定索引长度
    
    3.2.4 页面搜索严禁左模糊或者全模糊
    
    3.2.5 如果有order by的场景,请注意利用索引的有序性
    
    3.2.7 利用延迟关联或者子查询优化超多分页场景
    
    3.2.9 建组合索引的时候,区分度最高的在最左边

    上述规约主要讲的是和索引相关的内容。对于这块,笔者不是专业的DBA,所以只是挑了其中和程序开发特别有关的来讲一讲。

    比如3.2.2的禁止超过3个表的join,在笔者的团队中,规定更为严格:

    禁止超过2个表的join语句出现在程序中

    其实不许使用join是很多初级程序员非常不能理解的。要说明白这个问题,估计又要长篇大论,笔者会另辟文章进行说明。但这里还是引用一下robbin的观点(笔者表示深刻赞同):

    另外有关严禁使用全模糊查找,建组合索引时,区分度最高的往左放这些原则,在一定程度上会改变我们编写程序的习惯,所以应该时刻注意。

    
    3.3.5 在代码中写分页查询逻辑时,若count为0应直接返回,避免执行后面的分页语句
    
    3.3.6 不得使用外键与级联,一切外键概念必须在应用层解决
    
    3.3.7 禁止使用存储过程,存储过程难以调试和扩展,更没有移植性
    
    3.3.9 in操作能避免则避免,若实在避免不了,需要仔细评估in后边的集合元素数量,控制在1000个之内
    
    3.4.1 在表查询中,一律不要使用 * 作为查询的字段列表,需要哪些字段必须明确写明

    上面的这几条属于SQL编写规约。阿里的规范中洋洋洒洒讲了很多条,实际上都是在给程序员提个醒,笔者在这里不在赘述

    有关count(*)的争论,一直有大量的说法。此次阿里的规范总算为count(*)党找到了SQL标准,应该说也基本为这件事情画上了句号。

    有关外键和级联,笔者稍有困惑的是外键。因为按照笔者的理解,外键影响数据库插入的速度应该有限,与外键约束带来的好处相比,或许还是有外键更好一些(有这方面经验的读者可以留言指点迷津)。级联是恶魔,必须禁止。

    至于存储过程,或许Oracle出身的DBA会跳出来唱反调了。笔者的观点和阿里相同:存储过程很难移植和维护,应该抛弃

    有关表查询中不许使用 * 作为查询的字段列表,这点或许能够成为规约,但笔者并不十分认同。尤其是对于使用Hibernate作为ORM工具的同学来说,这条规则执行起来有难度。

    代码风格

    1.7.1 在一个switch块内,每个case要么通过break/return等来终止,要么注释说明程序将继续执行到哪一个case为止;
    在一个switch块内,都必须包含一个default语句并且放在最后,即使它什么代码也没有

    这条主要是期待程序员人为把握好代码的执行逻辑。对于switch语句,如果没有终止语句,会依次执行每一个case块。实际上,笔者认为switch语句是一个比较差的语法糖,通常情况下都可以用更加优雅的方式来写,包括并不限于使用设计模式。所以在笔者的团队中是禁止使用switch语句的。

    1.7 2 在if/else/for/while/do语句中必须使用大括号,即使只有一行代码,避免使用下面的形式:if (condition) statements;

    这一条比较有意思,因为这种一行式的代码风格,在javascript里面经常会看到,所以很多全栈工程师也会把它引入到Java中来。笔者对此并不反感,但确实在可读性上不那么友好。

    if(condition){
    ...
    return obj;
    }
    // 接着写else的业务逻辑代码;
    
    1.7.3 如果非得使用if()...else if()...else...方式表达逻辑,【强制】请勿超过3层,超过请使用状态设计模式

    上面这点笔者比较认同,因为else不仅会带来大段的代码缩进的困扰,同时也会降低代码的可读性。不过对于那些坚持必须在代码的最后一行统一return的同学,上面的写法可能就不太容易接受了。实际上,上述代码结构比较常见于Spring的源码中,倒不是尽早return,而是else的逻辑块可能直接throw异常出去了。

    1.7.4 除常用方法(如getXxx/isXxx)等外,不要在条件判断中执行其它复杂的语句,将复杂逻辑判断的结果赋值给一个有意义的布尔变量名,以提高可读性
    boolean existed = (file.open(fileName, "w") != null) && (...) || (...);
    if (existed) {
    ...
    }

    有关这一条,补充说明一下:将复杂的逻辑判断结果赋值给一个有意义的布尔变量名,除了提高可读性之外,实际上能够极大方便调试。但笔者认为单单只是抽取部分代码,并不能提高可读性,而是应该将复杂的逻辑判断进一步封装为一个方法

    上面的代码片段中,左边是阿里风格,右边是陆老师的风格,大家可以比较一下,哪个更好?哪个更符合面向对象的思维呢?

    1.7.5 循环体中的语句要考量性能,以下操作尽量移至循环体外处理,如定义对象、变量、获取数据库连接,进行不必要的try-catch操作

    这一条值得说一下,因为有些代码会走得比较深,写着写着就忘了它处于循环体的内部了。所以保持一个谨慎的心态比较重要。

    1) 调用频次低的方法。 
    2) 执行时间开销很大的方法,参数校验时间几乎可以忽略不计,但如果因为参数错误导致中间执行回退,或者错误,那得不偿失。
    3) 需要极高稳定性和可用性的方法。 
    4) 对外提供的开放接口,不管是RPC/API/HTTP接口。
    5) 敏感权限入口。
    
    1.7.8 方法中不需要参数校验的场景: 
    1) 极有可能被循环调用的方法,不建议对参数进行校验。但在方法说明里必须注明外部参数检查
    2) 底层的方法调用频度都比较高,一般不校验。毕竟是像纯净水过滤的最后一道,参数错误不太可能到底层才会暴露问题。一般DAO层与Service层都在同一个应用中,
    部署在同一台服务器中,所以DAO的参数校验,可以省略
    3) 被声明成private只会被自己代码所调用的方法,如果能够确定调用方法的代码传入参数已经做过检查或者肯定不会有问题,此时可以不校验参数

    这两条说的是参数校验,说的比较在理,也比较全面。比起很多公司的奇葩规定来说,要人性化得多。笔者认为需要补充的是:参数的校验主要还需要从格式和业务两个层面进行考量。业务层面的校验往往要比单纯的格式校验更为复杂,所以在写代码时可以建立一定层次的假设,当然这可能也会引入团队沟通的问题,需要根据实际情况权衡。

    有关阿里代码风格方面的解读,受限于阿里自身提出的规约比较少。对此,笔者是稍有失望的。因为代码风格规约是最能够体现一个团队对于代码整洁程度的一个衡量标准。所以笔者忍不住在这里多加了几条笔者团队的共识,供读者参考:

    在任何情况下,代码量越少越容易维护

    基于上面的原则,笔者的团队会鼓励使用三目表达式对简要的if/else进行重构

    当然,像下列左侧的代码,也会重构成右侧的:

     

    一个复杂的Service层逻辑,不应超过30行,否则需要进行逻辑规整和抽象

    在业务逻辑中尽可能不要使用setter方法,而是使用构造函数或者封装成一个有逻辑意义的方法,提高代码的可读性

    什么?连setter方法都不让用?这是什么SB一样的规约啊!事实上,笔者团队确实是这么做的,我们来看一下代码:

     

    在上面的代码中,左侧代码中的setter方法调用,会被封装到ShuttleOrder对象中的cancel方法中去。在实际的service代码中,只会出现下半部分的一行代码。

    这样做的好处在于:cancel这个方法被封装后,shuttleOrder.cancel()的调用从可读性上要明显优于使用2句setter方法,同时也为将来的逻辑扩展预留了位置。这也是面向对象的一种实践。


    展开全文
  • 谷歌代码规范

    千次阅读 2019-01-19 14:50:35
    英文版:http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml 中文版:... google c++ 编码规范:http://blog.csdn.net/xiexievv/articl...

    英文版:http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml

    中文版:http://zh-google-styleguide.readthedocs.org/en/latest/google-cpp-styleguide/

    google c++ 编码规范:http://blog.csdn.net/xiexievv/article/details/50972809

    网上有电子版 PDF ,可以下载看下。。。(电子版下载地址:https://pan.baidu.com/s/1i3gc7lF)

        Google C++ 编码规范很早就已经公开了,李开复也在其微博上公开分享:”我认为这是地球上最好的一份C++编程规范,没有之一,建议广大国内外IT研究使用。“
    
        Google C++ Style Guide是一份不错的C++编码指南,下面是一张比较全面的说明图,可以在短时间内快速掌握规范的重点内容。不过规范毕竟是人定的,记得活学活用。
    

    保持一致也非常重要,如果你在一个文件中新加的代码和原有代码风格相去甚远的话,这就破坏了文件本身的整体美观也影响阅读,所以要尽量避免。
    一些条目往往有例外,比如下面这些,所以本图不能代替文档,有时间还是把PDF认真阅读一遍吧。

    异常在测试框架中确实很好用
    
    RTTI在某些单元测试中非常有用
    
    在记录日志时可以使用流
    操作符重载 不提倡使用,有些STL 算法确实需要重载operator==时可以这么做。
    

    注:原图较大,在新标签页中打开或保存到本地打开更清晰

    在这里插入图片描述

    头文件

    函数参数顺序

    C/C++函数参数分为输入参数和输出参数两种,有时输入参数也会输出(注:值被修改时)。输入参数一般传值或常数引用(const references),输出参数戒输入/输出参数为非常数指针(non-const pointers)。对参数排序时,将所有输入参数置于输出参数之前。不要仅仅因为是新添加的参数,就将其置于最后,而应该依然置于输出参数之前。这一点并不是必须遵循的规则,输入/输出两用参数(通常是类/结构体变量)混在其中,会使得规则难以遵守。

    个人感受:这条规则相当重要,自己写代码的时候可能没有太大感觉,但是在阅读别人代码的时候感觉特别明显。如果代码按照这种规范来写,从某种角度来说,这段代码具有“自注释”的功能,那么在看代码的时候就会比较轻松。Doom3的代码规范中提到,“Use ‘const’ as much as possible”,也是同样的意义。当然,const除了阅读方便以外,还有个很重要的就是防止编码错误,一旦在程序中修改const变量,编译器就会报错,这样就减少了人工出错了可能性,这点尤为重要!

    包含文件的名称及次序

    将包含次序标准化可增强可读性、避免隐藏依赖(hidden dependencies,注:隐藏依赖主要是指包含的文件编译),次序如下:C 库、C++库、其他库的.h、项目内的.h。

    项目内头文件应挄照项目源代码目录树结构排列,并且避免使用UNIX文件路径.(当前目录)和…(父目录)。

    举例来说,google-awesome-project/src/foo/internal/fooserver.cc 的包含次序如下:
      #include “foo/public/fooserver.h” // 优先位置
      
      #include <sys/types.h>
      #include <unistd.h>

    #include <hash_map>
      #include

    #include “base/basictypes.h”
      #include “base/commandlineflags.h”
      #include “foo/public/bar.h”

    注意,对应的头文件一定要先包含,这样避免隐藏依赖,隐藏依赖的问题不懂的可以去Google,网上有很多资料。另外,《C++编程思想》中提到的包含次序正好相反,从特殊到一般,但是有一点和Google代码规范是一样的,那就是对应的头文件是第一个包含。对于隐藏依赖的问题,以前只是习惯性的把对应的头文件放第一个,没有想过为什么,现在学习了……

    作用域

    全局变量

    class 类型的全局变量是被禁止的,内建类型的全局变量是允许的,当然多线程代码中非常数全局变量也是被禁止的。永远不要使用函数返回值初始化全局变量。

    不幸的是,全局变量的构造函数、析构函数以及初始化操作的调用顺序只是被部分规定,每次生成有可能会有变化,从而导致难以发现bug。因此,禁止使用class类型的全局变量(包括STL的string,vector等),因为它们的初始化顺序可能会导致出现问题。内建类型和由内建类型构成的没有构造函数的结构体可以使用,如果你一定要使用class类型的全局变量,请使用单件模式。

    C++类

    构造函数的职责

    构造函数中只进行那些没有实际意义的初始化,可能的话,使用Init()方法集中初始化为有意义(non-trivial)的数据。

    个人感受:这种做法可以从一开始就避免一些bug的出现,或更容易解决一些bug。构造函数+Init()函数初始化的方式与只用构造函数的方法相比,对计算机来说他们是没有区别的,但是人是会犯错的,这一条代码规范在某种程度上避免了一些人为错误,这个在开发中特别重要。

    拷贝构造函数

    仅在代码中需要拷贝一个类的对象的时候使用拷贝构造函数,不需要拷贝时使用DISALLOW_COPY_AND_ASSIGN这个宏(关于这个宏的内容,可以在网上搜到,我这里就不写了)。C++中对象的隐式拷贝是导致很多性能问题和bugs的根源。拷贝构造函数降低了代码可读性,相比按引用传递,跟踪按值传递的对象更加困难,对象修改的地方变得难以捉摸。

    个人感受:和上一项的目的类似,为了避免人为错误!拷贝构造函数本来是为了方便程序员编程了,但是却有可能成为一个坑,为了避免这类问题,不需要拷贝时使用DISALLOW_COPY_AND_ASSIGN,这样在需要调用拷贝构造函数的时候就会报错,减少了人为出错的可能性。C#和Java在这方面就做得比较好,虽然性能上不如C++,但是人为出错的概率减少了很多。当然,使用一定的代码规范,可以在一定程度上减少C++的坑。

    继承

    虽然C++的继承很好用,但是在实际开发中,尽量多用组合少用继承,不懂的去看GoF的《Design Patterns》。

    但重定义派生的虚函数时,在派生类中明确声明其为virtual。这一条是为了为了阅读方便,虽然从语法的角度来说,在基类中声明了virtual,子类可以不用再声明该函数为virtual,但这样一来阅读代码的人需要检索类的所有祖先以确定该函数是否为虚函数o(╯□╰)o。

    多重继承

    虽然允许,但是只能一个基类有实现,其他基类是接口,这样一来和JAVA一样了。这些东西在C#和JAVA中都进行了改进,直接从语法上解决问题。C++的灵活性过高,也是个麻烦的问题,只能通过代码规范填坑。

    接口

    虚基类必须以Interface为后缀,方便阅读。阅读方便。

    重载操作符

    除少数特定情况外,不要重载操作符!!!“==”和“=”的操作Euqals和CopyFrom函数代替,这样更直观,也不容易出错。

    个人感受:看到这一条,我有点惊讶,在学习C++的时候,说重载操作符有神马神马好处,为什么现在又说不要重载操作符呢?仔细看了他的文档,确实说的有道理,导致可能出现的bug见其具体文档。在实际应用中,由于C++的坑实在太多了,不得不把这种“好用”的东西干掉,因为出了bug又找不到,是一件很O疼的事情。

    声明次序

    1)typedefs和enums;

    2)常量;

    3)构造函数;

    4)析构函数;

    5)成员函数,含静态成员函数;

    6)数据成员,含静态数据成员。

    宏 DISALLOW_COPY_AND_ASSIGN 置于private:块之后,作为类的最后部分。

    其他C++特性

    引用参数

    函数形参表中,所有的引用必须的const!

    个人感受:这么做是为了防止引用引起的误解,因为引用在语法上是值,却有指针的意义。虽然引用比较好用,但是牺牲其某些方面的特性,换来软件管理方面的便利,还是很值得了。

    缺省参数

    禁止使用函数缺省参数!

    个人感受:看到这一点的时候觉得有点因噎废食了,其实缺省参数感觉还是蛮好用的。当然从另外一个角度来说,要使用C++就不要怕这种小麻烦,如果因为使用这些特性造成了找不到的bug,那会损失更多时间。

    异常

    不要使用C++异常。

    这一点我没有看懂,也许是因为它的异常机制没有C#和Java那么完善吧……毕竟在C#和Java里面异常还是很好用的东东。

    除了记录日志,不要使用流,使用printf之类的代替。

    这一条其实是有一些争议的,当然大多数人认为代码一致性比较重要,所以选择printf,具体的可以看原文文档。

    const的使用

    在任何可以的情况下都要使用const。

    这条规则赞一个,Doom3的代码规范里也提到了这一条。这么做有两个好处,一个是防止程序出错,因为修改了const类型的变量会报错;另一个就是方便阅读,使代码“自注释”。虽然这么做也有坏处,当然,总体来说利大于弊。

    命名约定

    1、总体规则:不要随意缩写,如果说 ChangeLocalValue 写作ChgLocVal还有情可原的话,把ModifyPlayerName写作MdfPlyNm就太过分了,除函数名可适当为动词外,其他命名尽量使用清晰易懂的名词;

    2、宏、枚举等使用全部大写+下划线;

    3、变量(含类、结构体成员变量)、文件、命名空间、存取函数等使用全部小写+下划线,类成员变量以下划线结尾,全局变量以g_开头;

    4、普通函数、类型(含类与结构体、枚举类型)、常量等使用大小写混合,不含下划线;

    使用这套命名约定,可以使代码具有一定程度的“自注释”功能,方便他人阅读,也方便自己以后修改。当然3、4两点也可以使用其他的命名约定,只要团队统一即可。

    格式

    1、行宽原则上不超过80列,把22寸的显示屏都占完,怎么也说不过去;

    2、尽量不使用非ASCII字符,如果使用的话,参考 UTF-8 格式(尤其是 UNIX/Linux 下,Windows 下可以考虑宽字符),尽量不将字符串常量耦合到代码中,比如独立出资源文件,返不仅仅是风格问题了;

    3、UNIX/Linux下无条件使用空格,MSVC的话使用 Tab 也无可厚非; (我没用过Linux,不懂为什么在Linux下无条件使用空格)

    4、函数参数、逻辑条件、初始化列表:要么所有参数和函数名放在同一行,要么所有参数并排分行;

    5、除函数定义的左大括号可以置于行首外,包括函数/类/结极体/枚举声明、各种语句的左大括号置于行尾,所有右大括号独立成行;

    6、./->操作符前后丌留空格,*/&不要前后都留,一个就可,靠左靠右依各人喜好;

    7、预处理指令/命名空间不使用额外缩进,类/结构体/枚举/函数/语句使用缩进;

    8、初始化用=还是()依个人喜好,统一就好;

    9、return不要加();

    10、水平/垂直留白不要滥用,怎么易读怎么来。

    写在最后

    总的来说,这套代码规范还是相当不错的,既有防止错误使用C++的某些特性而导致bugs的规范,又有代码书写的相关规范使其便于阅读,建议搞C++的童鞋都看一看。当然,具体的团队应该会有具体的代码规范,代码风格方面大家可能会有一些区别;不使用C++某些特性(比如不使用C++异常,禁止使用函数缺省参数)方面,应该按照具体情况进行折中处理,而不应该生搬硬套代码规范;但是“不将字符串常量耦合到代码中”这种规范,是大家必须遵守的。

    转载:https://blog.csdn.net/freeking101/article/details/78930381 方便自己学习,感谢博主

    展开全文
  • 一、代码规范: 接口中分方法和属性,不加修饰符号如:publc,正确为:void f() long或Long,统一用Long类型处理 常量按功能分类归类 if/for/while/switch/do等保留字与括号之间都必须加空格 注释的双斜线与注释内容...
  • 代码规范

    2018-12-03 18:05:17
    代码规范 置顶 2018年04月18日 21:42:53 菜丸子 阅读数:1920 一、命名规约 1....
  • 代码规范代码规范

    2020-07-21 09:59:43
    代码规范代码规范代码规范代码规范代码规范代码规范代码规范代码规范代码规范
  • 【JAVA】代码规范

    千次阅读 2019-06-27 20:39:51
    一、命名规约 1.【强制】所有编程相关命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束。反例: _name / __name / $Object / name_ / name$ / Object$ 2.【强制】类名使用UpperCamelCase风格,...
  • 代码规范问题

    千次阅读 2018-09-28 10:06:34
    刚换工作,公司对于规范要求很高,虽然我是野路子出生的,没人教过我规范,但这不是理由,该掌握的东西还是得掌握,该注意的东西也得注意。废话不多说,反正大神随意,这里我只给那些新手做个参考。 反面例子: ...
  • python代码规范

    千次阅读 2018-09-28 12:55:04
    为什么要有代码规范? 1.做哪一行都有高低级别之分,别写一行代码就被人鄙视了 2.好的规范会形成好的编码风格,看着熟悉、亲切,心情好 3.增加可读性,易维护,提高工作效率 4.遵循规范,代码会自己写代码 5....
  • 代码编写规范

    千次阅读 2019-04-23 22:48:44
    排版格式2.1 类及其排版格式2.2 函数的声明与定义2.3 空行2.4 代码行2.5 代码行内的空格2.6 对齐2.7 长行拆分2.8 修饰符的位置2.9 代码段中的预处理格式2.10 被注释的代码2.11 注释3.命名规则4.表达式和基本语句4.1 ...
  • Java代码规范

    万次阅读 2019-12-23 08:54:07
    但是经常可能会出现跨模块调用其他人写的代码的情况,或者说是工作交接或者交叉原因,你要去看别人的代码,熟悉他的代码。这个时候就很头疼了,因为不同的人的代码习惯或者风格又不一样,你可能很看不惯...
  • IDEA安装阿里代码规范插件

    万次阅读 多人点赞 2020-06-13 11:55:53
    所以下载阿里的代码规范插件来约束自己凌乱的代码。阿里规范插件GitHub地址:https://github.com/alibaba/p3cIDEA安装该插件步骤:1.打开IDEA,File-&gt; Setteings-&gt;Plugins-&gt;Browse Repositorie...
  • Google 的 C++ 代码规范

    万次阅读 多人点赞 2019-12-16 15:25:59
    Google 开源项目风格指南 (中文版):https://zh-google-styleguide.readthedocs.io/en/latest/ 英文版:http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml 中文版:...
  • JS代码规范

    万次阅读 2020-06-19 09:48:28
    这是我所在公司所定义的代码规范精简版的分享给大家做参考 如果感觉不错请分享给更多的朋友! 1、使用const,let代替var 2、使用字面量创建对象和数组 new Object() => {} New Array() => [] 3、使用对象...
  • 前端代码规范手册

    千次阅读 2018-08-15 15:43:15
    前端代码规范手册       Web Coding Guidelines     前言 本手册的愿景是码出高效,码出质量。现代软件架构都需要协同开发完成,高效 协作即降低协同成本,提升沟通效率,所谓无规矩不成方圆,无规范不...
  • 目录 一、逻辑和数据 1、逻辑数据分离 2、逻辑的清晰性 3、逻辑的共性 4、数据的聚合性 5、数据的序列化 和 反序列化 二、常量 1、幻数(magic number) 2、枚举 3、增加枚举类型时的可行性 ... 3、lo...
  • 阿里巴巴代码规范

    千次阅读 2020-02-07 16:04:46
    本规范均出自阿里巴巴代码规范以及本人日常过程中的积累。由于篇幅有限,本文不予列出阿里巴巴代码规范的所有,仅列出本人觉得对日常使用过程中帮助较大且又是大家容易忽略的问题。 阿里巴巴代码规范:...
  • C语言代码规范(编程规范)

    千次阅读 多人点赞 2018-11-24 20:45:49
    C语言代码规范(编程规范) 什么叫规范?在C语言中不遵守编译器的规定,编译器在编译时就会报错,这个规定叫作规则。但是有一种规定,它是一种人为的、约定成俗的,即使不按照那种规定也不会出错,这种规定就叫作...
  • Vue开发代码规范

    千次阅读 2019-06-11 12:08:07
    首先说下契机,最近公司发生了几次由于不同人ide格式化差异...虽然由于平时开发除了eslint以外,对相关内容接触不多而碰到了不少坑,但是还是对代码规范以及git有了更深刻理解。 通过查看其它公司制定规范的案例和...
1 2 3 4 5 ... 20
收藏数 917,342
精华内容 366,936
关键字:

代码规范