当前位置: 首页 > news >正文

企业网站建站策划书新都区网站建设

企业网站建站策划书,新都区网站建设,道客网站建设推广,wordpress九宫格主题我重新理解了《重构》 重构的定义 《重构#xff1a;改善既有代码的设计》 书中给出了重构的定义#xff1a;对软件内部结构的一种调整#xff0c;目的是在不改变软件可观察前提下#xff0c;提高其可理解性#xff0c;降低其修改成本。每个人对重构有自己的理解#x…我重新理解了《重构》 重构的定义 《重构改善既有代码的设计》 书中给出了重构的定义对软件内部结构的一种调整目的是在不改变软件可观察前提下提高其可理解性降低其修改成本。每个人对重构有自己的理解我理解的重构重构是一种在不改变代码本身执行效果的前提下让代码变得更加整洁易懂的方式。代码不仅要让机器能够实现预期的处理逻辑更要能够面向开发人员简洁易懂便于后期维护升级。 为什么要重构 我对书中的一句话印象很深刻“减少重复代码保证一种行为表述的逻辑只在一个地方出现即使程序本身的运行时间、逻辑不会有任何改变但减少重复代码可以提高可读性降低日后修改的难度是优秀设计的根本”。回想在刚毕业工作不久时我也曾对同组师兄的代码重构意见有所疑惑重构本身可能不会改变代码实际的执行逻辑也不一定会对性能产生优化为什么一定要对代码的整洁度、可复用性如此执着结合书中的答案以及自己工作中的体会主要有以下几点 提升开发效率 在日常研发过程中首先需要理解已有代码再在已有代码基础上进行功能迭代升级。在开发过程中大部分时间用于阅读已有代码代码的可读性必然会影响开发效率。而在项目进度紧张的情况下为保证功能正常上线经常会出现过程中的代码可读性不强。如果没有后续重构优化在项目完成一段时间后当初的开发同学都很难在短时间内从代码看出当初设计时主要的出发点和以及需要注意的点后续维护成本高。因此通过重构增强代码的可读性更便于后续维护升级也有助于大部分问题通过CR阶段得以发现、解决。 降低修改风险 代码的简洁程度越高、可读性越强修改风险越低。 在实际项目开发过程中由于时间紧、工期赶优先保证功能正常往往权衡之下决定先上线后续再重构但随着时间的推移实际后续再进行修改的可能性很低暂且不谈后续重构本身的ROI对于蚂蚁这种极重视稳定性的公司后续的修改无疑会带来可能的风险秉持着“上线稳定运行了那么久的代码能不动尽量不要动”的思想当初的临时版本很有可能就是最终版本长此以往系统累积的临时代码、重复代码越来越多降低了可读性导致后续的维护成本极高。因此必要的重构短期看可能会增加额外成本投入但长期来看重构可以降低修改风险。 重构实践 减少重复代码 思前想后重构例子的第一条也是个人认为最重要的一条 就是减少重复代码。 如果系统中重复代码意味着增加修改风险当需要修改重复代码中的某些功能原本只应需要修改一个函数但由于存在重复代码修改点就会由1处增加为多处漏改、改错的风险大大增加。减少重复代码主要有两种方法一是及时删除代码迁移等操作形成的无流量的重复文件、重复代码二是减少代码耦合程度尽可能使用单一功能、可复用的方法坚持复用原则。 问题背景 在开发过程中未对之前的代码进行提炼复用存在重复代码。在开发时对于刚刚接触这部分代码的同学增加了阅读成本在修改重复的那部分代码时存在漏改、多处改动不一致的风险。 public PhotoHomeInitRes photoHomeInit() {if (!photoDrm.inUserPhotoWhitelist(SessionUtil.getUserId())) {LoggerUtil.info(LOGGER, [PhotoFacade] 用户暂无使用权限,userId, SessionUtil.getUserId());throw new BizException(ResultEnum.NO_ACCESS_AUTH);}PhotoHomeInitRes res new PhotoHomeInitRes();InnerRes innerRes photoAppService.renderHomePage();res.setSuccess(true);res.setTemplateInfoList(innerRes.getTemplateInfoList());return res; }public CheckStorageRes checkStorage() {if (!photoDrm.inUserPhotoWhitelist(SessionUtil.getUserId())) {LoggerUtil.info(LOGGER, [PhotoFacade] 用户暂无使用权限,userId, SessionUtil.getUserId());throw new BizException(ResultEnum.NO_ACCESS_AUTH);}CheckStorageRes checkStorageRes new CheckStorageRes();checkStorageRes.setCanSave(photoAppService.checkPhotoStorage(SessionUtil.getUserId()));checkStorageRes.setSuccess(true);return checkStorageRes; }重构方法及时清理无用代码、减少重复代码。 public PhotoHomeInitRes photoHomeInit() {photoAppService.checkUserPhotoWhitelist(SessionUtil.getUserId());PhotoHomeInitRes res new PhotoHomeInitRes();InnerRes innerRes photoAppService.renderHomePage();res.setSuccess(true);res.setTemplateInfoList(innerRes.getTemplateInfoList());return res; }public CheckStorageRes checkStorage() {photoAppService.checkUserPhotoWhitelist(SessionUtil.getUserId());CheckStorageRes checkStorageRes new CheckStorageRes();checkStorageRes.setCanSave(photoAppService.checkPhotoStorage(SessionUtil.getUserId()));checkStorageRes.setSuccess(true);return checkStorageRes; }public boolean checkUserPhotoWhitelist(String userId) {if (!photoDrm.openMainSwitchOn(userId) !photoDrm.inUserPhotoWhitelist(userId)) {LoggerUtil.info(LOGGER, [PhotoFacade] 用户暂无使用权限, userId, userId);throw new BizException(ResultEnum.NO_ACCESS_AUTH);}return true; }我们在系统中或多或少都看到过未复用已有代码产生的重复代码或者已经无流量的代码但对形成背景不了解出于稳定性考虑不敢贸然清理时间久了堆积越来越多。因此我们在日常开发过程中对项目产生的无用代码、重复代码要及时清理防止造成后面同学在看代码时的困惑以及不够熟悉背景的同学改动相关代码时漏改、错改的风险。 提升可读性 有效的注释 问题背景 业务代码缺乏有效注释需要阅读代码细节才能了解业务流程排查问题时效率较低。 ListString voucherMarkList CommonUtil.batchfetchVoucherMark(voucherList);if (CollectionUtil.isEmpty(voucherMarkList)) {return StringUtil.EMPTY_STRING;}BatchRecReasonRequest request new BatchRecReasonRequest();request.setBizItemIds(voucherMarkList);MapString, ListRecReasonDetailDTO recReasonDetailDTOMap relationRecReasonFacadeClient.batchGetRecReason(request);if (CollectionUtil.isEmpty(recReasonDetailDTOMap)) {return StringUtil.EMPTY_STRING;}for (String voucherMark : recReasonDetailDTOMap.keySet()) {ListRecReasonDetailDTO reasonDetailDTOS recReasonDetailDTOMap.get(voucherMark);for (RecReasonDetailDTO recReasonDetailDTO : reasonDetailDTOS) {if (needUpdateRecMaxCount(recReasonDetailDTO, RecReasonTypeEnum.FRIEND, recTypeList, friendRecMaxCount)) {friendRecText recReasonDetailDTO.getRecommendText();friendRecMaxCount recReasonDetailDTO.getCount();friendRecMaxCountDetailDTOS reasonDetailDTOS;continue;}if (needUpdateRecMaxCount(recReasonDetailDTO, RecReasonTypeEnum.LBS, recTypeList, lbsRecMaxCount)) {lbsRecText recReasonDetailDTO.getRecommendText();lbsRecMaxCount recReasonDetailDTO.getCount();}}return bulidRecText(friendRecMaxCountDetailDTOS, friendRecText, lbsRecText);重构方法补充相应的业务注释说明方法的核心思想和业务处理背景。 //1.生成对应的券标识查推荐信息ListString voucherMarkList CommonUtil.batchfetchVoucherMark(voucherList);if (CollectionUtil.isEmpty(voucherMarkList)) {return StringUtil.EMPTY_STRING;}BatchRecReasonRequest request new BatchRecReasonRequest();request.setBizItemIds(voucherMarkList);MapString, ListRecReasonDetailDTO recReasonDetailDTOMap relationRecReasonFacadeClient.batchGetRecReason(request);if (CollectionUtil.isEmpty(recReasonDetailDTOMap)) {return StringUtil.EMPTY_STRING;}//2.解析对应的推荐文案取使用量最大的推荐信息且好友推荐信息优先级更高for (String voucherMark : recReasonDetailDTOMap.keySet()) {ListRecReasonDetailDTO reasonDetailDTOS recReasonDetailDTOMap.get(voucherMark);for (RecReasonDetailDTO recReasonDetailDTO : reasonDetailDTOS) {//2.1 获取好友推荐信息if (needUpdateRecMaxCount(recReasonDetailDTO, RecReasonTypeEnum.FRIEND, recTypeList, friendRecMaxCount)) {friendRecText recReasonDetailDTO.getRecommendText();friendRecMaxCount recReasonDetailDTO.getCount();friendRecMaxCountDetailDTOS reasonDetailDTOS;continue;}//2.2 获取地理位置推荐信息if (needUpdateRecMaxCount(recReasonDetailDTO, RecReasonTypeEnum.LBS, recTypeList, lbsRecMaxCount)) {lbsRecText recReasonDetailDTO.getRecommendText();lbsRecMaxCount recReasonDetailDTO.getCount();}}//3.组装结果并返回若好友推荐量最大的券推荐信息中包含地理位置信息则返回组合文案(好友推荐信息与地理位置推荐信息均来自同一张券)return bulidRecText(friendRecMaxCountDetailDTOS, friendRecText, lbsRecText);重构这本书中表达了对注释的观点作者认为代码中不应有过多注释代码功能应该通过恰当的方法命名体现但相比于国内大多数工程师书中作者对英文的理解和运用更加擅长所以书中有此观点。但每个人的命名风格和对英文的理解不同仅通过命名不一定能快速了解背后的业务逻辑。个人认为业务注释而非代码功能注释清晰直观的业务注释能够在短时间内大致了解代码对应的业务逻辑可以帮助阅读者快速理解为什么这样做而不是做什么因此简洁的业务注释仍然是有必要的。 简化复杂的条件判断 问题背景 if语句中的判断条件过于复杂难以理解业务语义 for (RecReasonDetailDTO recReasonDetailDTO : reasonDetailDTOS) {//2.1 获取好友推荐信息if (StringUtil.equals(recReasonDetailDTO.getRecReasonType(), RecReasonTypeEnum.FRIEND.name()) recTypeList.contains(RecReasonTypeEnum.FRIEND.name()) StringUtil.isNotBlank(recReasonDetailDTO.getRecommendText()) recReasonDetailDTO.getCount() ! 0 Long.valueOf(recReasonDetailDTO.getCount()) friendRecMaxCount) {friendRecText recReasonDetailDTO.getRecommendText();friendRecMaxCount recReasonDetailDTO.getCount();friendRecMaxCountDetailDTOS reasonDetailDTOS;continue;} //2.2 获取地理位置推荐信息if (StringUtil.equals(recReasonDetailDTO.getRecReasonType(), RecReasonTypeEnum.LBS.name()) recTypeList.contains(RecReasonTypeEnum.LBS.name()) StringUtil.isNotBlank(recReasonDetailDTO.getRecommendText()) recReasonDetailDTO.getCount() ! 0 Long.valueOf(recReasonDetailDTO.getCount()) lbsRecMaxCount) {lbsRecText recReasonDetailDTO.getRecommendText();lbsRecMaxCount recReasonDetailDTO.getCount();} }重构方法将判断条件单独放在独立方法中并恰当命名提升可读性 for (RecReasonDetailDTO recReasonDetailDTO : reasonDetailDTOS) {//2.1 获取好友推荐信息if (needUpdateRecMaxCount(recReasonDetailDTO, RecReasonTypeEnum.FRIEND, recTypeList, friendRecMaxCount)) {friendRecText recReasonDetailDTO.getRecommendText();friendRecMaxCount recReasonDetailDTO.getCount();friendRecMaxCountDetailDTOS reasonDetailDTOS;continue;}//2.2 获取地理位置推荐信息if (needUpdateRecMaxCount(recReasonDetailDTO, RecReasonTypeEnum.LBS, recTypeList, lbsRecMaxCount)) {lbsRecText recReasonDetailDTO.getRecommendText();lbsRecMaxCount recReasonDetailDTO.getCount();}}private boolean needUpdateRecMaxCount(RecReasonDetailDTO recReasonDetailDTO, RecReasonTypeEnum reasonTypeEnum,ListString recTypeList, long recMaxCount) {if (StringUtil.equals(recReasonDetailDTO.getRecReasonType(), reasonTypeEnum.name()) recTypeList.contains(reasonTypeEnum.name()) StringUtil.isNotBlank(recReasonDetailDTO.getRecommendText()) recReasonDetailDTO.getCount() ! 0 Long.valueOf(recReasonDetailDTO.getCount()) recMaxCount) {return true;}return false;}将复杂的判断条件提炼到独立的方法中并通过恰当命名来帮助提升可读性。在阅读含有条件语句的代码时如果判断条件过于复杂容易将阅读注意力放在理解判断条件中而对方法整体的业务逻辑理解可能更困难耗时更久。因此简化判断条件并将其语义化更利于快速专注理解整体业务逻辑。 重构多层嵌套条件语句 问题背景 if条件多层嵌套影响可读性。在写代码的过程中保证功能正确的前提下按照思维逻辑写了多层条件嵌套正常的业务逻辑隐藏较深。开发者本身对业务流程足够熟悉可以一口气读完整段方法但对于其他同学来说在阅读此类型代码时读到正常逻辑时很容易已经忘记前面判断条件的内容对于前面的校验拦截印象不深。 if (Objects.nonNull(cardSaveNotifyDTO) !noNeedSendOpenCardMsg(cardSaveNotifyDTO)) {CardDO cardDO CardDAO.queryCardInfoById(cardSaveNotifyDTO.getCardId(),cardSaveNotifyDTO.getUserId());if (Objects.isNull(cardDO)) {LoggerUtil.warn(LOGGER, [CardSaveMessage] cardDO is null);return;}openCardServiceManager.sendOpenCardMessage(cardDO);LoggerUtil.info(LOGGER, [CardSaveMessage] send open card message, cardSaveNotifyDTO cardSaveNotifyDTO); }重构方法对于多层if嵌套的代码可以将不满足校验条件的情况快速返回增强可读性。 if (Objects.isNull(cardSaveNotifyDTO)) {LoggerUtil.warn(LOGGER, [CardSaveMessage] cardSaveNotifyDTO is null);return;}LoggerUtil.info(LOGGER, [CardSaveMessage] receive card save message, cardSaveNotifyDTO cardSaveNotifyDTO);if (noNeedSendOpenCardMsg(cardSaveNotifyDTO)) {LoggerUtil.info(LOGGER,[CardSaveMessage] not need send open card message, cardSaveNotifyDTO cardSaveNotifyDTO);return;}CardDO cardDO CardDAO.queryCardInfoById(cardSaveNotifyDTO.getCardId(),cardSaveNotifyDTO.getUserId());if (Objects.isNull(cardDO)) {LoggerUtil.warn(LOGGER, [CardSaveMessage] cardDO is null);return;}openCardServiceManager.sendOpenCardMessage(cardDO);LoggerUtil.info(LOGGER, [CardSaveMessage] send open card message, cardSaveNotifyDTO cardSaveNotifyDTO);如果是程序本身多种情况的返回值可以减少出口提升可读性。对于业务代码的前置校验更适合通过快速返回代替if嵌套的方式简化条件语句。虽然实际上实现功能相同但可读性及表达含义不同。用多分支if else表明多种情况出现的可能性是同等的而判断特殊情况后快速返回的写法表明只有很少部分出现其他情况所以出现后快速返回。简化判断条件更易让人理解业务场景。 固定规则语义化 问题背景 在开发过程中代码中存在包含多个枚举的组合或固定业务规则在阅读代码时不清楚背景容易产生困惑。例如图中所示代码在满足切换条件下将方法中的变量scene以默认的字符串拼接生成新的scene但这种隐含的默认规则需要阅读代码细节才能了解在排查问题时根据实际日志中的具体scene值来搜索也无法定位到具体代码理解成本高。 if (isMrchCardRemind(appId, appUrl)) {args.put(MessageConstant.MSG_REMIND_APP_ID, appId);args.put(MessageConstant.MSG_REMIND_APP_URL, appUrl);if (StringUtil.isNotBlank(memberCenterUrl)) {args.put(MessageConstant.MEMBER_CENTER_URL, memberCenterUrl);scene scene _WITH_MEMBER_CENTER;}scene scene _MERCH; }重构方法可以将其语义抽象为字段放入枚举中降低修改时的风险增强可读性 /*** 积分变动*/ CARD_POINT_UPDATE(CARD_POINT_UPDATE, CARD_POINT_UPDATE_MERCH, CARD_POINT_UPDATE_WITH_MEMBER_CENTER, CARD_POINT_UPDATE_MERCH_WITH_MEMBER_CENTER),/*** 余额变动*/ CARD_BALANCE_UPDATE(CARD_BALANCE_UPDATE, CARD_BALANCE_UPDATE_MERCH, CARD_BALANCE_UPDATE_WITH_MEMBER_CENTER, CARD_BALANCE_UPDATE_MERCH_WITH_MEMBER_CENTER),/*** 等级变动*/ CARD_LEVEL_UPDATE(CARD_LEVEL_UPDATE, CARD_LEVEL_UPDATE_MERCH, CARD_LEVEL_UPDATE_WITH_MEMBER_CENTER, CARD_LEVEL_UPDATE_MERCH_WITH_MEMBER_CENTER),if (isMrchCardRemind(appId, appUrl)) {args.put(MessageConstant.MSG_REMIND_APP_ID, appId);args.put(MessageConstant.MSG_REMIND_APP_URL, appUrl);if (StringUtil.isNotBlank(memberCenterUrl)) {args.put(MessageConstant.MEMBER_CENTER_URL, memberCenterUrl);return remindSceneEnum.getMerchRemindWithMemberScene();} return remindSceneEnum.getMerchRemindScene(); }在阅读代码了解业务细节时代码中的固定规则会额外增加阅读成本。在评估相关改动对现有业务影响时代码中包含固定规则需要特别注意。将固定规则语义化更有助于对已有代码理解和分析。如上例中将自定义的固定字符串拼接规则替换为枚举中的具体值虽然在重构后增加了代码行数但在提升可读性的同时也更便于根据具体值搜索定位具体代码其中枚举值的含义和关联关系更加清晰一目了然。 总结思考 代码的整洁度与代码质量成正比整洁的代码质量更高也更利于后期维护。重构本身不是目的目的是让代码更整洁、可读性更高、易于维护提升开发效率。 因此比起如何进行后续重构在开发过程中意识到什么样的代码是好代码在不额外增加太多研发成本的前提下 有意识地保持代码整洁更加重要。 即使是在日常开发过程中小的优化哪怕只有很少的代码改动只要能让代码更整洁仍然值得去做。 去除重复代码 重复代码包含代码迁移产生的过程代码、代码文件中重复的代码、相近的逻辑以及相似的业务流程。对于代码迁移产生的重复代码在迁移完成后要及时去除避免增加后续阅读复杂度。对于相似的功能函数以及相似的业务流程我们可以通过提炼方法、继承、模板方法等方式重构但与其后续通过重构手段消除代码更应在日常写代码的时候坚持合成复用原则减少重复代码。 恰当直观的命名 怎样的命名算是好的命名书中给出了关于命名的建议好的命名不需要用注释来补充说明直观明了通过命名就可以判断出函数的功能和用法提升可读性的同时便于根据常量的语义搜索查找。同理代码中有含义的数字、字符串要用常量替换的原则目的是相同的。在日常编码中要用直观的命名来描述函数功能。 例如用结合业务场景的用动词短语来命名在区分出应用场景的同时也便于根据业务场景来搜索相关功能函数。 单一职责避免过长的方法 看到书中提到避免过长的方法这样的观点时我也有这样的疑问多少行的方法算过长的方法对于函数多少行算长这个问题行数本身不重要重要的是函数名称与语义的距离。将实现每个功能的步骤提炼出独立方法虽然提炼后的函数代码量不一定大但却是如何做与做什么之间的语义转变提炼后的函数通过恰当直观命名可明显提升可读性。 以上总结了一些关于日常研发过程中应该坚持代码整洁原则的思考虽小但只要保持相信代码整洁度会有很大的提高共勉。
http://www.zqtcl.cn/news/948888/

相关文章:

  • 贵州建设水利厅考试网站wordpress主查询翻页
  • 网站优化网络推广seo天津建设工程信息网几点更新
  • 兰州网站seo技术厂家比较实用的h5网页建设网站
  • 怎样让自己做的网站被百度收录动漫制作软件
  • 西安网站制作哪家公司好怎么向企业推销网站建设
  • 电子商务网站建设新闻深圳坂田网站设计公司有哪些
  • 上海电子商城网站制作wordpress循环该分类子分类
  • 茶山做网站教育网站建设计划书
  • 成品门户网站源码免费海外网络加速器免费
  • 企业网站怎么建设公司深圳企业招聘信息最新招聘信息
  • 天津网站经营性备案下载网站上的表格 怎么做
  • 胶州企业网站设计十大互联网营销公司
  • 视频解析wordpresswordpress 优化版本
  • 柳州网站建设哪家便宜广东省建设厅三库一平台
  • 云南城市建设官方网站wordpress和织梦哪个好
  • 国外企业招聘网站专门做外贸的网站有哪些
  • 陕西交通建设集团网站营销公司是什么意思
  • 网站建设自建与租用区别杭州建设局网站官网
  • 广告公司企业介绍seo研究中心怎么样
  • 苏州网站建设熊掌岳阳做网站哪家好
  • 深圳网站制作公司报价单宝塔做两个网站6
  • 百度站长工具怎么查排名贵港网站制作
  • 运城个人网站建设学校网站建设目的
  • 住房城乡建设部门门户网站购物网站排名大全
  • 手机网站平台江门网站建设模板
  • 做本地网站需要什么资质百度多长时间收录网站
  • 网站建设公司使用图片侵权使用者有无责任夸克免费空间
  • 网站建设制作鸿运通做网站能用python吗
  • 站长源码之家Wordpress 新建标签
  • 太原网站建设详细策划如何建设网站简答题