如何写酷的代码.ppt_第1页
如何写酷的代码.ppt_第2页
如何写酷的代码.ppt_第3页
如何写酷的代码.ppt_第4页
如何写酷的代码.ppt_第5页
已阅读5页,还剩85页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

,目录,IF/SWITCH语句 复杂的、嵌套的IF/SWITCH语句,循环语句. 多层嵌套的循环语句,经常跟IF语句一起使用,A,B,圈复杂度 从理论上分析这两种坏味道,C,解决之道. 如何解决?值得探讨的课题,D,2,代码的坏味道带来的问题,破窗效应,代码的坏味道带来的问题,破窗效应,代码的坏味道带来的问题,破窗效应,代码的坏味道带来的问题,破窗效应,代码的坏味道带来的问题,冰山一角,代码的坏味道带来的问题,软件成本 Costtotal = costdevelop + costmaintain Costmaintain = Costunderstand + costchange + costtest+costdeploy 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 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 =orgDataService .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) (“EmpTreatmentController.getList()“); 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) Organization 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语句,5.难以理解 List list = roleJobService.getOrgRoleTypeByCode(tenantId,cod); if (list = null | list.size() = 0) return true; else for (OrgRoleType rgRoleType : list) if(rgRoleType.getIdx()=main.getIdx() return true; return false; ,代码的坏味道之IF语句,6.多此一举,if (list = null | list.size() = 0) return true; else return false; ,7.可以简化,if(size0) mail.setIsAttached(1); else mail.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.toLowerCase().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 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 != 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:“ + nationality ); 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.findMyJobsComments(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 ArrayList(); 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); return 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 orgJobMains.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 = PinYinUtil.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 ) roleNoChanelUp.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-) 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语句中的每一种情况加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(jobMain1.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 Complexity,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 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),学术成果,学术成果,圈复杂度,过去几年的各种研究已经确定: 圈复杂度大于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 : employeePositionList) 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 RedisCacheInterceptor. 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(bufKey); 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 .getEmployeePositionByOrgId(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 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 SalarySetPage getList(Integer currentPageNo, Integer pageSize, Long orgId) (“EmpTreatmentController.getList()“); if(currentPageNo = null | currentPageNo = 0) currentPageNo = 1; if(pageSize = null) pageSize = 2; SalarySetPage pager = empSalarySetService.getSalarySetPageByOrgIdx(getTenantId(), currentPageNo, pageSize, orgId); return pager; ,代码的坏味道之IF语句,3.使用默认值 public ResponseBody SalarySetPage getList(Integer currentPageNo, Integer pageSize, Long orgId) (“EmpTreatmentController.getList()“); if(currentPageNo = null | currentPageNo = 0) currentPageNo = 1; if(pageSize = null) pageSize = 2; SalarySetPage pager = empSalarySetService.getSalarySetPageByOrgIdx(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) (“EmpTreatmentController.getList()“); SalarySetPage 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(), 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语句,4.使用容易理解的临时变量 public String getDetaliOrgRoute(Long orgIdx, 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 getDetaliOrgRoute(fatherOrg.getIdx(), orgName, prefix); ,代码的坏味道之IF语句,5.综合修改 List list = roleJobService.getOrgRoleTypeByCode(tenantId,cod); if (list = null | list.size() = 0) return true; else for (OrgRoleType rgRoleType : list) if(rgRoleType.getIdx()=main.getIdx() return true; return false; ,代码的坏味道之IF语句,5.综合修改 List list = roleJobService.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; else return false; ,解决之道,mail.setIsAttached(size0?1:0);,7.使用表达式 if(size0) mail.setIsAttached(1); else mail.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().endsWith(“.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 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 by edt.deptIdx “); List list = deployTaskDao.findBySQL(sql.toString(); return list; else 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;,代码的坏味道之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 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:“ + nationality ); if(ethnic != 0) query.append(“ AND ETHNIC:“ + ethnic );,代码的坏味道之IF语句,10.使用循环代替重复的IF语句 String 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; for(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) 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,Long 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 CompanyCommentPager 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 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.getPagerGetter(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 /* * 按empcode排序方法 * param group * return */ public static List sortByEmpcode( List group) List groupEmp = new ArrayList(); 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); return groupEmp; ,代码的坏味道之FOR循环,1.使用API /* * 按empcode排序方法 * param group * return */ public static void sortByEmpcode( List group) Collections.sort(list1, new Comparator() public int compare(EmployeePosition o1, EmployeePosition o2) return compareToEmpcode(postion.getEmp().getEmpCode(), groupEmp .get(n).getEmp().getEmpCode() ; ); ,代码的坏味道之FOR循环,注意:数组也有sort API 在Arrays类里。,注意:类似的方法 在Collections类和Arrays类里,有这样一些方法: 1.binarySearch 2.max 3.min 4. frequency 5. Reverse 请使用这些方法来避免不必要的FOR循环,谢谢!,代码的坏味道之FOR循环,其他一些避免FOR循环的方法 1.求两个集合的并集 addAlll 2.求两个集合的交集 retain

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论