您好,欢迎访问三七文档
代码整洁之道2015年12月梅花与剑目录01代码的坏味道02编码原则03代码可读性04代码健壮性05异常处理06关于日志07关于性能08代码习惯09设计模式10关于重构这是哪个傻X写的代码!!!•世上本没有BUG•随着功能的增加,便有了BUG•老的BUG改了,可能引入新的BUG•事实1:我们的软件,在发布前,其实就已经百病缠身了。代码如何变烂的?熟悉代码的坏味道,并知道这里需要重构,代码的坏味道(部分):重复代码—拷贝粘贴再修改的痕迹(提取公共逻辑)过长的方法—函数体超过50行,实现了多个逻辑(ExtractMethod)过大的类—类做了太多的事情(ExtractClass)过长的参数列—方法难于使用和理解(参数Object化)变化导致太多修改—变化引起多个类的修改(Move方法到该放的地方)依恋情节—一个类的实现大量引用另一个类的数据(Move方法)Switch语句—对不同类别使用switch(使用多态)临时变量—临时变量不易于理解和抽取(ReplaceTempwithQuery)过度设计—过多的抽象和代理(先简单设计,变化来临时再重构)不用的方法—子类不需要使用父类的方法(改变类层次)违背了一些原则—后面会详细讲原则及违背带来的影响代码的坏味道低质量代码存在的问题:难于变化—一处变化导致其它很多部分,特别是无关部分的修改难于重用—系统关联性过多,导致很难分离可重用部分不必要的复杂—设计过于复杂,不利于当前编码不必要的重复—同样的逻辑多处出现,未进行抽象的统一难于理解—命名杂乱,结构混乱,难于阅读和理解难于测试和验证—过多依赖其它系统,缺乏完善测试体系,难于验证高质量的代码编写原则:每个变量只用于单一用途每一行代码只表达一件事一个循环只做一件事单一抽象层次原则函数应该遵守单一职责函数圈复杂度应该小于10函数第一原则是必须要短小编写函数时必须一心一意、专注、怀有谦虚的心态原则八大原则代码可读性——目录结构测试目录编译后的class文件存放目录数据库建库脚本目录Java目录Java测试目录Web目录业务处理基类读取配置文件db_config.xml数据库操作封装日志操作封装Servlet基类常用操作类封装按业务功能模块拓展控制类继承base下的Servlet基类业务类继承base下的业务处理基类配置文件(数据库配置和日志配置)图片目录不同类的图片放在不同目录下各种引入文件如样式文件、脚本文件、jsp头尾文件jsp文件目录,按业务功能模块拓展,与java业务模块划分对应common是公共内容,如错误提示、分页等class文件、第三方jar包、配置文件web工程:webapp:src:代码可读性——包、类、方法、属性、常量的命名规范myname可能的写法:myname、my_name、MyName或者myName。两种常用命名方法:驼峰式命名:printEmployeePaychecks();函数名中的每一个逻辑断点都有一个大写字母来标记下划线法命名:print_employee_paychecks();函数名中的每一个逻辑断点都有一个下划线来标记骆驼式命名法就是当变量名或函式名是由一个或多个单字连结在一起,而构成的唯一识别字时,第一个单词以小写字母开始;第二个单词的首字母大写或每一个单词的首字母都采用大写字母。小驼峰法:除第一个单词之外,其他单词首字母大写。譬如intmyStudentCount;大驼峰法:相比小驼峰法,大驼峰法把第一个单词的首字母也大写了。譬如publicclassDataBaseUser;Package的命名Package的名字应该都是由一个小写单词组成。Class的命名Class的名字必须由大写字母开头而其他字母都小写的单词组成,大驼峰法Class变量的命名变量的名字必须用一个小写字母开头。后面的单词用大写字母开头,小驼峰法StaticFinal变量的命名StaticFinal变量的名字应该都大写,并且指出完整含义,下划线法方法的命名方法的名字的第一个单词应以小写字母作为开头,后面的单词则用大写字母开头。小驼峰法代码可读性——判断中尽量少用“非”看一段代码inta=2;intb=5;if(!(a!=1&&b==5)){System.out.println(“条件1”);}else{System.out.println(“条件2”);}请问输出是什么?如果觉得这还不够,那看看“我不得不否认,你不是个笨蛋”,这句话是什么意思:)杜绝双重否定的出现,代码是用来给人读的代码可读性——i++和++i看一段代码:publicclassTestStatic{static{intx=5;}staticintx,y;publicstaticvoidmain(Stringarg[]){x++;method();}publicstaticvoidmethod(){System.out.println(x+++++y);}}X和y分别是多少不要写这类代码,这种代码是用来考机器的,对于我们要写的代码,请写大家看得懂的代码真实代码:PublicClassCounter{privateintcounter=0;publicintgetCounter(){return++counter;}}由于运行环境的不同,有些返回1,有些返回0代码可读性——注释•文件头标注开发者、功能、开发时间、最后修改时间、修改详情;•方法头标注功能、输出参数、输入参数;•方法体内重要代码及疑难代码行内注释;•ifelse类代码优先考虑标注,标注在右大括号之后;•数据成员、数据操作分组,两者之间空一行区分;•方法之间空一行;•采用垂直对齐,tab缩进,以保证代码上下整齐;•嵌套(如ifelse及for)一般不要超过三层;代码健壮性——空指针问题这段代码有什么问题没有?publicStringtest(Stringpara){……if(para.equals(“”)){para=“default”;……}……}如果para是null,将会怎样,java.lang.NullPointerException异常对于是否为空的判断,有没有更好的办法.equals(para)代码健壮性——除数0看一段代码:publicfloattest(floata,floatb){floatc;c=(a-b)/breturnc;}除数是0是否进行判断publicfloattest(floata,floatb){floatc;if(b==0){c=0;}else{c=(a-b)/b;}returnc;}有没有更好的办法?代码健壮性——数据格式转换看一段代码:StringsMemberid=request.getParameter(memberid);intiMemberid=Integer.parseInt(sMemberid);是否存在问题?try{StringsMemberid=request.getParameter(memberid);intiMemberid=Integer.parseInt(sMemberid);……}catch(NumberFormatExceptione){//如何处理}在任何用到字符串转化为数字时,捕捉异常,对异常情况进行处理。这样,在编程时稍微麻烦一点,但可以保证模块更加健壮。代码健壮性——in还是notin有一个应用场景烟叶类型,当前有烤烟、白肋烟和香料烟三种,统计烤烟和白肋烟的数量条件用烟叶类型in(“烤烟”,“白肋烟”)还是烟叶类型!=“香料烟”?当增加一种烟叶类型“马里兰烟”另一种场景,雪茄烟,显示非雪茄烟卷烟类型增加一种新的类型关于函数——函数的目的为什么需要函数如果程序的功能比较多,规模比较大,把所有代码都写在一个函数中,就会使这个函数变得庞杂、头绪不清,阅读和维护变得困难。有时程序中要多次实现某一功能,就需要多次重复编写实现此功能的程序代码,这使程序冗长,不精炼。复杂——简单模糊——清晰重复——复用(灵活)关于函数——单一抽象层次原则单一抽象层次原则SLAP(SingleLevelofAbstractionPrinciple):让一个方法中的所有操作处于相同的抽象层。publicvoidperformTask(HttpServletRequestrequest,HttpServletResponseresponse){RightCheckrc=newRightCheck();RequestAnalysisra=newRequestAnalysis();ResponseVOrvo=null;try{ServicrVOsvo=ra.requestAnalysis(request);rvo=rc.rightCheck(svo);}catch(Exceptione){//异常处理}PrintWriterout=null;try{out=response.getWriter();out.write(rvo.getResponseResult());}catch(IOExceptione){//异常处理}finally{if(out!=null)out.close();}}关于函数——单一职责原则函数应该做一件事,做好这件事,只做这件事publicvoidperformTask(HttpServletRequestrequest,HttpServletResponseresponse){StringuserName=request.getParameter(userName);StringBuffersql=newStringBuffer(“”);sql.append(“select*fromT_TEST);if(!“”.equals){sql.append(“whereuser_name=‘”).append(userName).append(“’”);}PageDBBeanpageDBBean=newPageDBBean();try{userList=(List)pageDBBean.executeQueryPage(sql,nCurrentPage,10,UserVO.class.getName());}catch(Exceptione){//异常处理}finally{pageDBBean.close();}Stringurl=“/jsp/user.jsp”request.setAttribute(userList,userList);forward(request,response,url);}关于函数——短小原则函数第一原则:是要短小函数第二原则:是还要短小函数第三原则:是必须短小重要的事情说三遍尽量使每件事变得简单,并且知道不可能再简单为止。你认为一个函数最大的行数应该控制多少行?想想你最近写的代码是否做到了50行数据库相关——数据库连接看一段代码publicvoidtest(String[]para){DBBeanBasedbbean=newDBBeanBase(true);StringBuffersql=getSQL(para);//一个复杂的处理生成sql,一般需要5stry{if(dbbean.executeUpdate(sq)0){result=成功;}}catch(Exceptione){dbbean.rollback();//异常处理}finally{dbbean.close();}}有什么问题异常处理——捕获、处理和抛出看一段代码FileOutputStreamfileOUT=null;try{fileOUT=newFileOutputStream(d:\test.txt);……}catch(FileNotFoundExceptione1){//TODOAuto-generatedcatchblocke1.printStackTrace();}有什么问题异常处理——finally的使用publicvoidfoo()throwsIOException{//
本文标题:代码整洁之道
链接地址:https://www.777doc.com/doc-4933050 .html