《如何写酷的代码.ppt》由会员分享,可在线阅读,更多相关《如何写酷的代码.ppt(90页珍藏版)》请在三一办公上搜索。
1、,目录,IF/SWITCH语句 复杂的、嵌套的IF/SWITCH语句,循环语句.多层嵌套的循环语句,经常跟IF语句一起使用,A,B,圈复杂度 从理论上分析这两种坏味道,C,解决之道.如何解决?值得探讨的课题,D,2,代码的坏味道带来的问题,破窗效应,代码的坏味道带来的问题,破窗效应,代码的坏味道带来的问题,破窗效应,代码的坏味道带来的问题,破窗效应,代码的坏味道带来的问题,冰山一角,代码的坏味道带来的问题,软件成本Costtotal=costdevelop+costmaintainCostmaintain=Costunderstand+costchange+costtest+costdeplo
2、y Costmaintain costdevelop,代码的坏味道之IF语句,1.判断集合不为空,if(employeePositionList!=null,2.判断对象不为空,if(empSalarySet.getEffictiveDate()!=null if(empSalarySet.getInvalDate()!=null&empSalarySet.getInvalDate()!=).,代码的坏味道之IF语句,3.判断不为空 byte bufKey=RedisCacheInterceptor.stringSerializer.serialize(session.getId();byte
3、 bufValue=connection.get(bufKey);if(bufValue!=null)try return RedisCacheInterceptor.javaSerializer.deserializeInto(bufValue,session);catch(IOException e)e.printStackTrace();catch(ClassNotFoundException e)e.printStackTrace();return null;,代码的坏味道之IF语句,3.判断不为空 if(orgId!=null)List employeePositionList=or
4、gDataService.getEmployeePositionByOrgId(getTenantId(),orgId);Map empMap=new HashMap();List empList=new ArrayList();if(employeePositionList!=null,代码的坏味道之IF语句,4.判断为空 public ResponseBody SalarySetPage getList(Integer currentPageNo,Integer pageSize,Long orgId)logger.info(EmpTreatmentController.getList()
5、;if(currentPageNo=null|currentPageNo=0)currentPageNo=1;if(pageSize=null)pageSize=2;SalarySetPage pager=empSalarySetService.getSalarySetPageByOrgIdx(getTenantId(),currentPageNo,pageSize,orgId);return pager;,代码的坏味道之IF语句,5.读不懂 public String getDetaliOrgRoute(Long orgIdx,String orgName,String prefix)Org
6、anization org=orgDataService.getOrgById(getTenantId(),orgIdx);if(org.getUplink()!=0)Organization fatherOrg=orgDataService.getOrgById(getTenantId(),org.getUplink();orgName=fatherOrg.getOrgName()+prefix+orgName;return getDetaliOrgRoute(fatherOrg.getIdx(),orgName,prefix);else return orgName;,代码的坏味道之IF语
7、句,5.难以理解 List list=roleJobService.getOrgRoleTypeByCode(tenantId,cod);if(list=null|list.size()=0)return true;elsefor(OrgRoleType rgRoleType:list)if(rgRoleType.getIdx()=main.getIdx()return true;return false;,代码的坏味道之IF语句,6.多此一举,if(list=null|list.size()=0)return true;elsereturn false;,7.可以简化,if(size0)ma
8、il.setIsAttached(1);elsemail.setIsAttached(0);.,代码的坏味道之IF语句,8.永远不会执行的条件 if(lis!=null,代码的坏味道之IF语句,9.错误的思路public void uploadPhoto(RequestParam(file)CommonsMultipartFile file,Long id,HttpServletResponse response)if(file!=null)String errorStr=null;FTPUtil ftpUtil=new FTPUtil();try if(!fileName.toLowerCa
9、se().endsWith(.jpg).,代码的坏味道之IF语句,10.IF语句带来整个逻辑的复杂public List getEntryOrgAndCount(Long empIdx)StringBuffer sql=new StringBuffer(select edt.deptIdx,count(*)as deptCount from eb_deploy_task edt where 1=1);if(empIdx!=null)sql.append(and edt.empIdx=+empIdx);sql.append(and edt.status=10);sql.append(group
10、by edt.deptIdx);List list=deployTaskDao.findBySQL(sql.toString();return list;else return null;,代码的坏味道之IF语句,11.重复的IF语句if(sex!=0)query.append(AND sex:+sex);if(resumeFrom!=0)query.append(AND RESUME_FROM:+resumeFrom);if(residencyType!=0)query.append(AND RESIDENCY_TYPE:+residencyType);if(contractStatus!=
11、0)query.append(AND CONTRACT_STATUS:+contractStatus);if(contractType!=0)query.append(AND CONTRACT_TYPE:+contractType);if(pop!=0)query.append(AND pop:+pop);if(religion!=0)query.append(AND RELIGION:+religion);if(race!=0)query.append(AND RACE:+race);if(nationality!=0)query.append(AND NATIONALITY:+nation
12、ality);if(ethnic!=0)query.append(AND ETHNIC:+ethnic);,代码的坏味道之IF语句,12.IF语句的扩展性问题public ResponseBody Pager findJobComments(Long companyId,Long jobId,Integer type,Integer pageNo,Integer w)long userId=getUser().getId();if(pageNo=null)pageNo=0;Pager pager=null;if(type=0)pager=jobCommentSerice.findMyJobsC
13、omments(userId,jobId,type,pageNo,w);return pager;else if(type=1)pager=companyCommentService.findMyCompanyComments(userId,companyId,type,pageNo,w);return pager;return null;,代码的坏味道之FOR循环,1.不该存在的FOR循环,排序/*按empcode排序方法*param group*return*/public static List sortByEmpcode(List group)List groupEmp=new Arr
14、ayList();EmployeePosition postion;for(int m=0;m group.size();m+)boolean flag=true;postion=group.get(m);for(int n=0;n groupEmp.size();n+)if(!compareToEmpcode(postion.getEmp().getEmpCode(),groupEmp.get(n).getEmp().getEmpCode()groupEmp.add(n,postion);flag=false;break;if(flag)groupEmp.add(postion);retur
15、n groupEmp;,代码的坏味道之FOR循环,1.不该存在的FOR循环,排序问题if(jobMains!=null,代码的坏味道之FOR循环,2.多重循环for(int k=0;k orgJobMains=orgDataService.getOrgJobMainByOrgId(tenantId,orgs.get(k).idx);if(stdJobs!=null)for(int j=0;j stdJobs.size();j+)if(stdJobs.get(j).status!=1L)isOk=false;if(orgJobMains!=null)for(int i=0;i orgJobMai
16、ns.size();i+)if(stdJobs.get(j).getIdx()=orgJobMains.get(i).uplink|(orgs.get(k).getOrgName()+stdJobs.get(j).jobName).equals(orgJobMains.get(i).jobName)isOk=false;if(isOk)OrgJobMain jobMain=new OrgJobMain();jobMain.setUpdateBy(getUser().getIdx();.jobMain.setLayer(stdJobs.get(j).layer);String reCode=Pi
17、nYinUtil.converterToFirstSpell(jobMain.jobName).toUpperCase();isOk=true;,代码的坏味道之FOR循环,3.查找 boolean exist=false;for(EmpSalaryDetail detail:details)if(detail.getPackageType()=packageTypesi,4.难以理解的循环for(int i=0;iroleNoChanelUp.size();i+)if(roleNoChanelUp.get(i).getUnderDept().getUplink()=0)roleNoChanel
18、Up.remove(i);i=i-1;,代码的坏味道之FOR循环,5.分层错误if(list=null|list.size()=0),代码的坏味道之FOR循环,6.没有必要的循环 JSONArray roleMainJSONArray=if(roleNoChanelUp!=null,7.循环补全 int companyIdStrLength=corpIdx.length();for(int i=0;i 6-companyIdStrLength;i+)corpIdx=0+corpIdx;.,代码的坏味道之FOR循环,8.集合删除for(int i=roleMains.size()-1;i=0;i
19、-)orgRoleMain=roleMains.get(i);if(sta=1,圈复杂度,圈复杂度是一种度量方法。由Thomas McCabe于1975年定义.圈复杂度是一个方法中执行路径的数量。,圈复杂度(Cyclomatic Complexity,CC),圈复杂度(Cyclomatic Complexity,CC),计算程序中的圈复杂度 1.从1开始,一直往下通过程序,计算程序中的圈复杂度2.一旦遇到以下的关键字,或者其他同类词,加1(if/while/for/and/or),圈复杂度(Cyclomatic Complexity,CC),计算程序中的圈复杂度 3.给case语句中的每一种情
20、况加1,圈复杂度(Cyclomatic Complexity,CC),例子,RequestMapping(value=/editPage,method=RequestMethod.POST)public ResponseBody JSONMessage editPage(OrgJobMain orgJobMain)OrgJobMain jobMain1=positionService.getOrgJobMainById(getUser().getTenantId(),orgJobMain.getIdx();JSONMessage message=new JSONMessage();if(job
21、Main1.jobCode!=null j+)if(jobMains.get(i).layer=jobMains.get(j).layer),圈复杂度(Cyclomatic Complexity,CC),例子,if(jobMains.get(i).getJobCode()!=null,圈复杂度(Cyclomatic Complexity,CC),例子,if(i 0,圈复杂度(Cyclomatic Complexity,CC),例子,jobMain1.setEffectiveDate(orgJobMain.getEffectiveDate()!=null,圈复杂度(Cyclomatic Comp
22、lexity,CC),例子,RequestMapping(value=/editPage,method=RequestMethod.POST)public ResponseBody JSONMessage editPage(OrgJobMain orgJobMain)OrgJobMain jobMain1=positionService.getOrgJobMainById(getUser().getTenantId(),orgJobMain.getIdx();1 JSONMessage message=new JSONMessage();3 if(jobMain1.jobCode!=null
23、j+)8 if(jobMains.get(i).layer=jobMains.get(j).layer),圈复杂度(Cyclomatic Complexity,CC),例子,10 if(jobMains.get(i).getJobCode()!=null,圈复杂度(Cyclomatic Complexity,CC),例子,21 if(i 0,圈复杂度(Cyclomatic Complexity,CC),例子,25 jobMain1.setEffectiveDate(orgJobMain.getEffectiveDate()!=null,圈复杂度(Cyclomatic Complexity,CC
24、),学术成果,学术成果,圈复杂度,过去几年的各种研究已经确定:圈复杂度大于10的方法存在很大的出错风险。1-4 is low complexity,5-7 indicates moderate complexity,8-10 is high complexity,and 11+is very high complexity.,圈复杂度,正常的程序员看上去很难处理好5-9个以上的智力实体,并且提高的可能性不大,因此,你只能减低你程序的复杂度。Miller 1995,圈复杂度(Cyclomatic Complexity,CC),解决之道,for(EmployeePosition ep:employ
25、eePositionList)empMap.put(ep.getEmp().getIdx(),ep.getEmp();empList.addAll(empMap.values();,1.集合返回非null对象if(employeePositionList!=null,代码的坏味道之IF语句,2.使用卫语句 byte bufKey=RedisCacheInterceptor.stringSerializer.serialize(session.getId();byte bufValue=connection.get(bufKey);if(bufValue!=null)try return Red
26、isCacheInterceptor.javaSerializer.deserializeInto(bufValue,session);catch(IOException e)e.printStackTrace();catch(ClassNotFoundException e)e.printStackTrace();return null;,代码的坏味道之IF语句,2.使用卫语句 byte bufKey=RedisCacheInterceptor.stringSerializer.serialize(session.getId();byte bufValue=connection.get(bu
27、fKey);if(bufValue!=null)return null;try return RedisCacheInterceptor.javaSerializer.deserializeInto(bufValue,session);catch(IOException e)e.printStackTrace();catch(ClassNotFoundException e)e.printStackTrace();return null;,代码的坏味道之IF语句,2.使用卫语句 if(orgId!=null)List employeePositionList=orgDataService.ge
28、tEmployeePositionByOrgId(getTenantId(),orgId);Map empMap=new HashMap();List empList=new ArrayList();if(employeePositionList!=null,代码的坏味道之IF语句,2.使用卫语句 if(orgId!=null)pager.setSuccess(false);return;List employeePositionList=orgDataService.getEmployeePositionByOrgId(getTenantId(),orgId);Map empMap=new
29、HashMap();List empList=new ArrayList();for(EmployeePosition ep:employeePositionList)empMap.put(ep.getEmp().getIdx(),ep.getEmp();empList.addAll(empMap.values();empList=EmployeeMainSorter.sortByEmpcode(empList);pager.setRoot(empList);pager.setSuccess(true);,代码的坏味道之IF语句,3.使用默认值 public ResponseBody Sala
30、rySetPage getList(Integer currentPageNo,Integer pageSize,Long orgId)logger.info(EmpTreatmentController.getList();if(currentPageNo=null|currentPageNo=0)currentPageNo=1;if(pageSize=null)pageSize=2;SalarySetPage pager=empSalarySetService.getSalarySetPageByOrgIdx(getTenantId(),currentPageNo,pageSize,org
31、Id);return pager;,代码的坏味道之IF语句,3.使用默认值 public ResponseBody SalarySetPage getList(Integer currentPageNo,Integer pageSize,Long orgId)logger.info(EmpTreatmentController.getList();if(currentPageNo=null|currentPageNo=0)currentPageNo=1;if(pageSize=null)pageSize=2;SalarySetPage pager=empSalarySetService.get
32、SalarySetPageByOrgIdx(getTenantId(),currentPageNo,pageSize,orgId);return pager;,代码的坏味道之IF语句,3.使用默认值 public class Page private Integer currentPageNo=1;private Integer pageSize=2;public ResponseBody SalarySetPage getList(Page currPage,Long orgId)logger.info(EmpTreatmentController.getList();SalarySetPa
33、ge pager=empSalarySetService.getSalarySetPageByOrgIdx(getTenantId(),currPage.getCurrentPageNo(),currPage.getPageSize(),orgId);return pager;,代码的坏味道之IF语句,4.使用容易理解的临时变量 public String getDetaliOrgRoute(Long orgIdx,String orgName,String prefix)Organization org=orgDataService.getOrgById(getTenantId(),orgI
34、dx);if(org.getUplink()!=0)Organization fatherOrg=orgDataService.getOrgById(getTenantId(),org.getUplink();orgName=fatherOrg.getOrgName()+prefix+orgName;return getDetaliOrgRoute(fatherOrg.getIdx(),orgName,prefix);else return orgName;,代码的坏味道之IF语句,4.使用容易理解的临时变量 public String getDetaliOrgRoute(Long orgId
35、x,String orgName,String prefix)Organization org=orgDataService.getOrgById(getTenantId(),orgIdx);boolean isSuperiorOrg=org.getUplink()=0;if(isSuperiorOrg)return orgName;Organization fatherOrg=orgDataService.getOrgById(getTenantId(),org.getUplink();orgName=fatherOrg.getOrgName()+prefix+orgName;return
36、getDetaliOrgRoute(fatherOrg.getIdx(),orgName,prefix);,代码的坏味道之IF语句,5.综合修改 List list=roleJobService.getOrgRoleTypeByCode(tenantId,cod);if(list=null|list.size()=0)return true;elsefor(OrgRoleType rgRoleType:list)if(rgRoleType.getIdx()=main.getIdx()return true;return false;,代码的坏味道之IF语句,5.综合修改 List list=r
37、oleJobService.getOrgRoleTypeByCode(tenantId,cod);if(list.size()=0)return true;for(OrgRoleType rgRoleType:list)if(rgRoleType.getIdx()=main.getIdx()return true;return false;,解决之道,return list=null|list.size()=0;,6.直接返回if(list=null|list.size()=0)return true;elsereturn false;,解决之道,mail.setIsAttached(size
38、0?1:0);,7.使用表达式if(size0)mail.setIsAttached(1);elsemail.setIsAttached(0);,代码的坏味道之IF语句,8.用返回代替判断public void uploadPhoto(RequestParam(file)CommonsMultipartFile file,Long id,HttpServletResponse response)if(file!=null)String errorStr=null;FTPUtil ftpUtil=new FTPUtil();try if(!fileName.toLowerCase().endsW
39、ith(.jpg).,代码的坏味道之IF语句,8.用返回代替判断public void uploadPhoto(RequestParam(file)CommonsMultipartFile file,Long id,HttpServletResponse response)if(file!=null)String errorStr=null;FTPUtil ftpUtil=new FTPUtil();try if(!fileName.toLowerCase().endsWith(.jpg),代码的坏味道之IF语句,9.直接返回+表达式public List getEntryOrgAndCoun
40、t(Long empIdx)StringBuffer sql=new StringBuffer(select edt.deptIdx,count(*)as deptCount from eb_deploy_task edt where 1=1);if(empIdx!=null)sql.append(and edt.empIdx=+empIdx);sql.append(and edt.status=10);sql.append(group by edt.deptIdx);List list=deployTaskDao.findBySQL(sql.toString();return list;el
41、se return null;,代码的坏味道之IF语句,9.直接返回+表达式public List getEntryOrgAndCount(Long empIdx)if(empIdx=null)return null;String sql=select edt.deptIdx,count(*)as deptCount from eb_deploy_task edt where edt.empIdx=?and edt.status=10 group by edt.deptIdx;List list=deployTaskDao.findBySQL(sql,empIdx);return list;,
42、代码的坏味道之IF语句,10.使用循环代替重复的IF语句if(sex!=0)query.append(AND sex:+sex);if(resumeFrom!=0)query.append(AND RESUME_FROM:+resumeFrom);if(residencyType!=0)query.append(AND RESIDENCY_TYPE:+residencyType);if(contractStatus!=0)query.append(AND CONTRACT_STATUS:+contractStatus);if(contractType!=0)query.append(AND C
43、ONTRACT_TYPE:+contractType);if(pop!=0)query.append(AND pop:+pop);if(religion!=0)query.append(AND RELIGION:+religion);if(race!=0)query.append(AND RACE:+race);if(nationality!=0)query.append(AND NATIONALITY:+nationality);if(ethnic!=0)query.append(AND ETHNIC:+ethnic);,代码的坏味道之IF语句,10.使用循环代替重复的IF语句String
44、keyWords=new String AND sex:,AND RESUME_FROM:,AND RESIDENCY_TYPE:,AND CONTRACT_STATUS:,AND CONTRACT_TYPE:,AND pop:,AND RELIGION:,AND RACE:,AND NATIONALITY:,AND ETHNIC:;int valueWords=new intsex,resumeFrom,residencyType,contractStatus,contractStatus,contractType,pop,religion,race,nationality,ethnic;f
45、or(int i=0;ikeyWord.size();i+)if(valueWordsi!=0)query.append(keyWordsi+valueWordsi);,代码的坏味道之IF语句,11.使用对象解决IF语句扩展问题public ResponseBody Pager findJobComments(Long companyId,Long jobId,Integer type,Integer pageNo,Integer w)long userId=getUser().getId();if(pageNo=null)pageNo=0;Pager pager=null;if(type=0
46、)pager=jobCommentSerice.findMyJobsComments(userId,jobId,type,pageNo,w);return pager;else if(type=1)pager=companyCommentService.findMyCompanyComments(userId,companyId,type,pageNo,w);return pager;return null;,代码的坏味道之IF语句,11.使用对象解决IF语句扩展问题public class PagerGetter public Pager getPager(Integer userId,Lo
47、ng jobId,Integer type,Page page);public Pager JobCommentPager implements PagerGetter public Pager getPager(Integer userId,Long jobId,Integer type,Page page)return jobCommentSerice.findMyJobsComments(userId,jobId,type,page.getPageNo,page.getW()a);,代码的坏味道之IF语句,11.使用对象解决IF语句扩展问题public Pager CompanyComm
48、entPager implements PagerGetter public Pager getPager(Integer userId,Long jobId,Integer type,Page page)return companyCommentSerice.findMyJobsComments(userId,jobId,type,page.getPageNo,page.getW()a);public class PagerGetterFactory public static PagerGetter getPagerGetter(Integer type)if(type=0)return
49、new JobCommentPager();else if(type=1)return new CompanyCommentPager();,代码的坏味道之IF语句,11.使用对象解决IF语句扩展问题public ResponseBody Pager findJobComments(Long companyId,Long jobId,Integer type,Integer pageNo,Integer w)long userId=getUser().getId();if(pageNo=null)pageNo=0;PagerGetter pg=PagerGetterFactory.getPag
50、erGetter(type);return pg.getPager(userId,jobId,type,new Pager(pageNo,w);return null;,代码的坏味道之IF语句,11.使用对象解决IF语句扩展问题 进一步的扩展,type设定为类名:public class PagerGetterFactory public static PagerGetter getPagerGetter(Integer type)return(PagerGetter)Class.forName(type).newInstance();,代码的坏味道之FOR循环,1.使用API/*按empco