请选择 进入手机版 | 继续访问电脑版

设为首页 收藏本站
思科社区 关注
思科社区

   思科 CCO 登录 推荐
 找回密码
 立即注册

搜索
热搜: 邮件服务器
查看: 429|回复: 0

【原创翻译】有效的代码重构(4)

[复制链接]
发表于 2019-6-14 15:37:21 | 显示全部楼层 |阅读模式
第4部分:重写代码
通过上述部分,您应该已经制定出了计划、选取了相应任务、编写出了测试,那么是否现在就可以开始打开某个文件、修正变量名称并清理代码了呢?为了确保重构的顺利进行,我建议您先熟悉一些基本的概念。
下面,我将向您介绍一些在代码重构过程中的常见错误和化繁为简的技巧。
识别自动化的可能性
您很可能会碰到需要移动并梳理到正确的位置的大量文件。例如,我曾经在重构一个应用时发现其Redux的actions、reducers、和selectors都分属于自己单独的文件夹,而我需要将它们按照模块(例如appActions.js、appReducer.js和appSelectors.js)进行分类。因此,我需要运行一条git mv的命令,将 /actions/app.js移动到/redux/app/appActions.js,并且对于/reducers/app.js和/selectors/app.js要执行相同的操作。由于该应用项目中有11个模块,因此我必须输入33次git mv命令。另外,我还需要再运行150次git mv,以将React的容器和组件放置到正确的文件夹位置。
因此,面对如此“崩溃”的任务,我并没有手动地逐条输入命令,而是使用JavaScript和Node.js编写了一个脚本来实现:
const fs = require('fs');
const path = require('path');
const chalk = require('chalk');
const sh = require('shelljs');
const _ = require('lodash');
const sourcePath = path.resolve(process.cwd(), 'src');
// This is the new /src/redux folder that getscreated:
const reduxPath = path.resolve(sourcePath, 'redux');
// I used "entities" instead of"modules", but they represent the same thing:
const entities = [
  'app',
  'projects',
  'schedules',
  'users',
];
const createReduxFolders = () => {
  if(!fs.existsSync(reduxPath)) fs.mkdirSync(reduxPath);
  // Code to create entities folders in /src/redux...
};
// Executes a `git mv` command (I omitted someadditional code that validates
// if the file already exists for brevity).
const gitMoveFile = (sourcePath, targetPath) => {
console.log(chalk.cyan(`Moving ${sourcePath} to ${targetPath}`));
  const command = `git mv ${sourcePath} ${targetPath}`;
  sh.exec(command);
console.log(chalk.green('Move successful.'));
};
const moveReduxFiles = () => {
entities.forEach(entity => {
    ['actions', 'reducers', 'selectors'].forEach(reduxType => {
      // Get the file associated with the specifiedentity for the specified reduxType,
      // so the first file might be /src/actions/app.js:
      const sourceFile = path.resolve(sourcePath, reduxType, `${entity}.js`);
      if(fs.existsSync(sourceFile)) {
        // Capitalize the reduxType to append to the filename (e.g. appActions.js):
        const fileSuffix = _.capitalize(reduxType);
        // Build the path to the target file, so this wouldbe /src/redux/app/appActions.js:
        const targetPath = `${reduxPath}/${entity}`;
        const targetFile = `${targetPath}/${entity}${fileSuffix}.js`;
        // Execute a `git mv` command for the file:
       gitMoveFile(sourceFile, targetFile);
      }
    });
  });
};
moveReduxFiles();


您既可以通过脚本来自动迁移文件的路径,也可以通过脚本来直接修改路径的名称。当然,您需要注意投入产出比,不要花费了20小时去编写一个脚本,却只是节省了1个小时手动工作量。由于大多数代码库、及其结构都相对独特,因此一般您编写脚本的复用性都不高。
持续提交
您所重构的应用程序越多、时间越长,就越难以记住和追踪那些在不同文件里的细微修改。而对于各种文件的累计且大量更改,势必给您应用测试来带来失败的风险。因此,无论代码的修改量大或小、多或少,请记得予以持续提交。以某次应用重构为例,我就进行了1,747次提交,涉及到659个文件中的76,080行代码,总体占用的存储空间为10MB。
另外,在多次且持续的提交过程中,您可以通过限制每一次更改的内容和文件的数量,以便您能够随时按需“跳回”到某一个可靠的“保存点”。
抵御“分心”
请暂时避免清理那些手头任务范围之外的代码,这也是代码重构过程中最困难的方面之一。假设您遇到了一个使用Object.assign()的selector,而您的后续任务之一便是更新代码,使用类似spread syntax新的ESNext功能(请参考https://developer.mozilla.org/en ... ators/Spread_syntax)。那么请不要偏离当前的任务走向,哪怕只是对该代码进行微不足道的改变,都不要放在现在进行。我的经验是:在相应的代码处添加了一条// REFACTOR: Fix this later的注释,然后继续自己的当前任务。
有关拉取请求的方法论
有时候,您花费了大量的时间去清理一部分代码库,而难以后退到过去的某个时间点,或无法对修改后的代码质量进行评估。那么拉取请求往往就能够帮助您和同事来评审这些修改,以确定是否有益于代码的优化。
·        当您在提交拉取请求时,请在摘要处给予尽可能详细的描述。如果您使用的是GitHub,那么新的拉取请求会伴随着一个模板。您可以在其中填写相应的标题、总体描述、重要章节的变更列表等各种审评人员所关注的信息。
·        您需要注意的一个指标是:与拉取请求相关的代码更改数量。请尽量限制更改的代码行数在500行左右。由于Jest快照文件的添加会使得拉取请求动辄添加数千行,因此请务必在摘要中包含与之相关的注释。
·        如果您无法控制改变的数量,那么就请尽量降低其复杂性。
·        如果您只是对重要的声明语句进行重新排序的话,只要此类更改并不太复杂,超过2,000行的代码量还是可以接受的。
·        请将同类变更尽量限定在同一次拉取请求之中。
·        您可以大胆地在注释中写上“本次并未做逻辑上的修改”,以节约审阅者的理解时间。

写在最后
上面我们从代码重构项目的实施角度,向您提供了:尽可能自动化、持续提交、抵御“分心”、以及善用拉取请求等方面的建议。如果您还想深入了解代码重构的更多信息,请参考如下的资源链接:
·        重构:改进现有代码的设计(https://martinfowler.com/books/refactoring.html
·        清理代码:敏捷软件的工艺手册(https://www.amazon.com/Clean-Cod ... nship/dp/0132350882

【原标题】 Effective Refactoring (作者: Mike Rourke)
原文链接:https://dzone.com/articles/effec ... king-the-right-ques


  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5
平均得分0 (0 评价)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver | 思科社区  

GMT+8, 2019-11-18 22:39 , Processed in 0.096622 second(s), 34 queries .

京ICP备09041801号-187

版权所有 :copyright:1992-2019 思科系统  重要声明 | 保密声明 | 隐私权政策 | 商标 |

快速回复 返回顶部 返回列表