代码编写原则
这应该是我第一次使用简书发文章,之前一直都在CSDN上写文章,无意之中看到了简书这个平台,发现其展示效果更加符合我的预期风格,于是开始尝试在这上面发布一些自己的文章。
以下内容均来自我日常写代码过程之中的理解以及读过Code Complete 2[代码大全2]之后真正沉淀下来的东西。
变量命名
变量命名是所有编程人员都必须要做的工作,每个公司和个人也都有自己的风格(我也不例外),及时一千个人眼里有一千个哈姆雷特,这里面还是有一定的通用规则,下面我们一一道来。
(1).命名长度:个人认为合适的命名长度应该是在10-17个字符之间,当然有一些简单的变量可能通过更短的命名解决,但是这里希望给出的一种通用的规则。太长的名字例如:numberOfPeopleOnTheUsOlypicTeam,numberOfSeatsInTheStadium等等,这些虽然可以清楚的反映出变量名字的含义,但是不管是阅读还是书写上都有很大的障碍。太短的例如:n,np,max等等,很多都是我们初学时候使用的变量,这种变量估计只有当事人才可以真正的理解其含义。长度适中的有:numTeamMembers,teamMembersTotal,seatCount这种,既能看出变量的具体含义(当然需要结合变量出现的大环境),长度又保持了适中。
(2).计算值限定词: 计算值限定词就是我们平时使用的解释数量相关的一些词语,比如我们经常使用的Sum,Max,Average这种类型的词语。我们经常需要从一系列数据中产出如何我们要求的数据,比如均值,最大最小值等等。那么我们在变量中如何表示呢,我曾经在公司中看到过这样的变量:personCount,totalPerson,maxGrade,gradeMin...这种问题是我经常遇到的不规范问题,每个人与每个人的编写习惯都不一样,有的人习惯把限定词放到前面,有的人喜欢放后面,这导致了我们编写过程之中遇到麻烦。就上的例子而言,其实personCount和totalPerson变量的意思一样,都是用户总量的意思,但是由于是不用的人编写,所以导致了重复。现在给出常用的规范:personCount,gradeMax,gradeMin,gradeAverage。把限定词都放在后面使用,这样根据我们从左往右读数据的习惯,我们首先看到的是变量的属性,这往往也是我们首先关心的,然后看到的是限定词,在代码排布上也显的比较整齐。还有一点就是关于num 的使用,经常看到numCustomers,customerNum这种,前者的num表示总量,后面的num代表下标,这种num的通用会影响我们的使用,所以建议废弃num,使用更合适的量词代替。表示总量时候可以是用Count或者Total,表示下标时候使用Index。
(3).变量风格:变量风格指的是我们在项目中编写变量的习惯,例如下划线类型:person_count,user_alive;驼峰类型:personCount,userAlive。基本上这些都是我们经常遇到的,在java中普遍使用的是驼峰类型,其他语言例如C++中我们看到下划线类型会多一点。所以我们在项目中一定要采用统一的命名类型,要么是下划线,要么是驼峰,不能同时出现。
(4).全局状态变量:全局状态变量值得是一些特定的数据变量(基本上是定值),我们一般会在类的开头或者一个专门的文件中声明这些变量方便后面调用。针对这类变量我们采用默认约定的变量命名规则:大写加下划线. 例如:ALIVE_STATUS,CONNECTION_NAME.
(5).枚举类型变量:枚举类型的变量采用的统一模型是:大写字母开头加小写字母,中间用下划线分割。例如:Color_Red,Color_Blue.但是这里有一点需要强调的是为了防止过多枚举类型的带来的疑惑,我们统一都在枚举类型变量前面加上前缀,相当于对变量归属的进一步说明,比如上面的Color就是我们添加的前缀。
(6).布尔类型变量:在这里我首先需要强调的是对于status的使用,很多同学习惯使用status表示某个变量的状态,而不管它有多少个状态。在这里给出规范性建议:如果变量有多于两个状态则可以使用Status,如果仅有两个或者少于两个的状态则严禁使用Status,应该使用更用描述性的词语.例如:success,found,done,alive等等.这种变量的好处是我们在做If判断的时候可以这样子:if(found)-->含义一目了然。尽量不使用否定的变量,例如:notFound,notDone,这样我们在做判断的时候就要if(!notFound)-->双重否定带来的结果是不方便阅读,因此应该尽量避免。
(7).对仗词:对仗词就是一些同时出现的前后照应的词语组合,下面给出这些常用的组合:begin/end,first/last,locked/uplocked,min/max,next/pervious,old/new,opened/closed,visible/invisible,source/target(destination),up/down,head/tail....
函数编写
(1).函数命名:函数一般是作为一个功能代码块,首选要保证的是其功能的单一性,所以函数名称要一定体现出其功能。例如process(),compute()这种函数的命名其实就太过粗糙,我们容易产生疑惑就是process what,compute what?看起来这种词语具有很强的描述性,其实太过粗糙,我们往往应该进一步去描述其方法名:computeUserStatus,processHandleResult等等。当然函数单一性这个规范也有一定例外,但是只限于少数,例如我们就在ORM中经常看到saveOrUpdate()这种方法。
(2).函数(代码)内容控制:其实这一块内容可以放到函数里面讲,也可以放到代码内容里面讲。我就稍微偷个懒统一在这里说一下好了。
(2.1):避免跳来跳去的代码:首先我们看下什么是跳来跳去的代码:
这中代码就出现在同类处理事件中,我们看起来往往会非常费劲,如果类似的步骤多了之后看起来就更费劲了,往往一页还处理不了需要翻页处理。为了能够从头往尾阅读,我们通常把相关的代码组织在一起:
现在我们完全不用跳跃地阅读了,我们把相关的代码都集中写在一个位置了,这样的话我们容易将不同的类分割开来检查,而且也更符合人么的阅读习惯。这种代码我们也成为直线型代码。
(2.2):变量定义尽量靠近使用的地方:其实这里是一个稍微有争议的地方,因为大多数的成员变量我们都习惯在类的开始就进行定义或者处理花,然后变量下面才是方法的声明和逻辑的编写,这样的好处就是变量在统一的地方定义,检查起来方便;但是弊端就是某些变量使用时候距离定义的位置相隔太远,在对业务代码不熟悉的情况下往往需要到一个类的顶部才能确定这个变量。及时有这种弊端存在,为了代码的整洁性,我还是支持这种结构的。现在我要说的函数内的变量定义。因为函数的长度一般都保持在百行以内,很多人觉得这时候变量定义的位置都随意了,反正代码这么短随便在哪里都能一眼看得到,但是作为一个优秀的编程人员,一定对自己是严格要求的。下面给出我的建议:变量定义尽量靠近初次使用变量的位置。这样做的好处是我们能够将局部代码更加紧凑化的展现出来,在视觉上也不会产生跳跃感,更不会因为变量多的时候产生疑惑或者健忘。在代码大全中还给出了一种衡量规则,有兴趣的同学可以参考一下。
(2.3):if-else编写的注意事项:平时我们在写if-else语句时候可能没有注意到的一个问题就是判断逻辑的顺序问题。例如:
这种写法我相信大家不会陌生,眨眼一看没有什么大问题。但是我现在给定一个适用场景,这是一个中国消费人群年龄普查计算,那么这里就有一点问题了。我们知道消费人群的大多数比例都在10岁以上,也就是说10岁以上的比重占得最多,其次是50岁以上和10岁以下,下面对这个语句进行改变:
改进的地方就是将出现比例最高的选项放在If判断的最前位置,这样做的好处就是可以尽快结束if判断。当然有些时候无法判断哪个判断条件成立的条件更大点,这时候就只能"随性"一点书写了。所以整体的建议就是:将成立概率高的条件写在判断的最前面,然后根据成立概率依次往下书写。同样的建议也适用于case编写。
以上的说明都是我印象最深刻也是记忆最深刻的地方,至于类编写过程的保证类功能单一,合理的内部类抽象,类的划分等等这些感觉都不太好讲清楚,而且也是自己对这方面理解还不到位,所以暂时没有写出来。如果有哪位大牛对这方面也有自己的见解可以贴出来大家共同学习一下。