您还未登录! 登录 | 注册 | 帮助  

您的位置: 首页 > 软件开发专栏 > 开发技术 > 正文

软件工程师必备的五种生产力增强方式与实践

发表于:2020-12-24 作者:陈峻编译 来源:51cto

在如今全球疫情持续蔓延的情况下,人们往往希望通过各种生产力的增强方式,来替代当前无法面对面开展高效协作的状况。在本文中,我们将和您讨论五种有助于软件工程师和技术公司提高工作效率的实用方式,其中包括:设计系统(Design systems)、代码查询器(code linters),代码格式工具(code formatters)、持续集成(continuous integration)、以及IaaS/PaaS平台(IaaS/PaaS providers)。它们能够帮助您在不牺牲软件产品质量的情况下,加快整个开发周期和交付进程。

设计系统

设计系统主要包含了各种设计模式、使用指南、文档、所有权模型、沟通方法、以及产品路线图等。我们可以简单地把它理解为一个根据可重用的构建块(building blocks),来创建某个产品的组件库。此处的构建块主要包括:图标生成器(avatars)、标志、按钮、下拉菜单、输入表单、图标、链接、模式、进度指示器、以及工具提示等组件。就像乐高积木一样,这些组件可以被组合起来,以创建应用程序必需的所有页面和功能。

为了使软件产品的用户界面(UI)能够随着业务与功能不断扩展,设计系统能够给用户带来如下好处:

  1. 设计系统可帮助您创建一致性的UI,以便您在整个应用程序中都使用统一的构件块组件。
  2. 设计系统通过提供一种可以在任何地方实现的通用模式,以方便设计师和软件工程师加快开发的速度,而不必花费数小时、甚至数天的时间去重构模式。
  3. 您可以使用一组共享的组件,来轻松地在整个应用中一次性进行模式的更改。例如:如果您需要更改某个应用的按钮样式,那么就无需逐个进行调整,而只需在设计系统中统一更改,以便直观地应用到任何使用相关按钮的地方。
  4. 设计系统使您更加专注于提升用户体验(UX)。用户体验设计师无需花费时间,去逐个决定每个新功能的下拉菜单和模式该如何工作,而是只需在整体上,集中确保其合理性和用户友好度即可。

目前,市场上有许多设计系统类工具可供选用,其中包括:Google的Material-UI、Adobe的Spectrum、以及Ant Design等。当然,如果您有足够的时间和资源的话,也可以自行构建设计系统。

编码查看器

上图是针对JavaScript的ESLint的截图。它通过对代码进行静态分析,协助自动捕获各种语法错误,以及潜在的运行问题。此类查看器不但短小精悍,并且能够直接被包含在您的构建过程或git hook中。毕竟,它们最擅长的,便是通过自动化执行,在海量代码中发现各种语法上、以及逻辑上的错误。

以上面提到的ESLint为例,它不但具有高度可配置性,并且具有广泛的插件生态系统。您可以通过安装eslint -plugin-jsx-a11y之类的ESLint插件,来协助捕获应用程序中的违规访问行为;或者是通过安装eslint-plugin-react,来协助实现React的各种优秀实践。当然,如果您不想花时间自己去挑选插件的话,也可以使用一些预设好的插件。例如:eslint-config-airbnb插件包,就预设好了一些由Airbnb推荐的ESLint配置项。

代码格式化工具

诸如Prettier之类的格式化工具,可以对您的JavaScript、HTML、CSS、乃至各种Markdown文件,进行格式化与规范化。与代码查看器类似,代码格式化工具可以自动化执行,各种原本需要软件工程师手动完成的任务。

通过预先配置,Prettier能够对应该使用的空格、制表符、分号、逗号等各种代码格式予以自动规范化。在节省代码审查时间的同时,团队不但可以在整个存储库中保持一致性和标准化,还能够腾出更多的时间,专注于代码本身的功能、以及可维护性。

如下Java代码是Prettier配置的示例:


  1. {   
  2. 2   
  3.   "tabWidth": 2,   
  4. 3   
  5.   "useTabs": false,   
  6. 4   
  7.   "printWidth": 80,   
  8. 5   
  9.   "semi": false,   
  10. 6   
  11.   "singleQuote": true,   
  12. 7   
  13.   "trailingComma": "es5",   
  14. 8   
  15.   "quoteProps": "as-needed",   
  16. 9   
  17.   "jsxSingleQuote": false,   
  18. 10   
  19.   "jsxBracketSameLine": false,   
  20. 11   
  21.   "bracketSpacing": true,   
  22. 12   
  23.   "arrowParens": "avoid",   
  24. 13   
  25.   "endOfLine": "auto",   
  26. 14   
  27.   "proseWrap": "preserve",   
  28. 15   
  29.   "htmlWhitespaceSensitivity": "css"   
  30. 16   
  31. }   

我们来看一个例子。显然,下面的Java程序代码,看上去十分杂乱无章:


  1. function HelloWorld({greeting = "hello", greeted = '"World"', silent = false, onMouseOver,}) {   
  2. 2   
  3. 3   
  4.   if(!greeting){return null};   
  5. 4   
  6. 5   
  7.      // TODO: Don't use random in render   
  8. 6   
  9.   let num = Math.floor (Math.random() * 1E+7).toString().replace(/\.\d+/ig, "")   
  10. 7   
  11. 8   
  12.   return <div className='HelloWorld' title={`You are visitor number ${ num }`} onMouseOver={onMouseOver}>   
  13. 9   
  14. 10   
  15.     <strong>{ greeting.slice( 0, 1 ).toUpperCase() + greeting.slice(1).toLowerCase() }</strong>   
  16. 11   
  17.     {greeting.endsWith(",") ? " " : <span style={{color: '\grey'}}>", "</span> }   
  18. 12   
  19.     <em>   
  20. 13   
  21.     { greeted }   
  22. 14   
  23.     </em>   
  24. 15   
  25.     { (silent)   
  26. 16   
  27.       ? "."   
  28. 17   
  29.       : "!"}   
  30. 18   
  31. 19   
  32.     </div>;   
  33. 20   
  34. 21   
  35. }   

通过使用Prettier,代码会变成如下的样子:


  1. function HelloWorld({   
  2. 2   
  3.   greeting = 'hello',   
  4. 3   
  5.   greeted = '"World"',   
  6. 4   
  7.   silent = false,   
  8. 5   
  9.   onMouseOver,   
  10. 6   
  11. }) {   
  12. 7   
  13.   if (!greeting) {   
  14. 8   
  15.     return null   
  16. 9   
  17.   }   
  18. 10   
  19. 11   
  20.   // TODO: Don't use random in render   
  21. 12   
  22.   let num = Math.floor(Math.random() * 1e7)   
  23. 13   
  24.     .toString()   
  25. 14   
  26.     .replace(/\.\d+/gi, '')   
  27. 15   
  28. 16   
  29.   return (   
  30. 17   
  31.     <div   
  32. 18   
  33.       className="HelloWorld"   
  34. 19   
  35.       title={`You are visitor number ${num}`}   
  36. 20   
  37.       onMouseOver={onMouseOver}   
  38. 21   
  39.     >   
  40. 22   
  41.       <strong>   
  42. 23   
  43.         {greeting.slice(0, 1).toUpperCase() + greeting.slice(1).toLowerCase()}   
  44. 24   
  45.       </strong>   
  46. 25   
  47.       {greeting.endsWith(',') ? (   
  48. 26   
  49.         ' '   
  50. 27   
  51.       ) : (   
  52. 28   
  53.         <span style={{ color: 'grey' }}>", "</span>   
  54. 29   
  55.       )}   
  56. 30   
  57.       <em>{greeted}</em>   
  58. 31   
  59.       {silent ? '.' : '!'}   
  60. 32   
  61.     </div>   
  62. 33   
  63.   )   
  64. 34   
  65. }    

自动化测试和持续集成

随着应用程序在复杂性和代码体量上的增长,我们再也无法单靠一己之力,手动测试目标应用中涉及到的所有内容。我们需要进行动作分解,通过自动化测试来完成单元测试、集成测试、端到端(E2E)测试、以及回归测试。

由DevOps理念带来的持续集成(CI)实践,则能够确保您代码的主分支在理论上,一直处于可执行的状态。为此,您可以使用Travis CICircleCIGitLab CI/CD、以及Heroku CI之类的服务,来为存储库设置持续集成。在此基础上,您可以通过配置CI管道,以便在每次提交后,运行查看器和自动化测试,进而在满足所有前续条件的基础上,实现代码合并。实践证明,相对于手动测试,自动化测试和持续集成都能够大幅减少整个开发周期的用时。

IaaS和PaaS平台

在如今云服务盛行的时代,我们要学会善用基础架构即服务(IaaS)和平台即服务(PaaS),来管理应用的基础架构。目前,常见的IaaS平台包括Amazon Web ServicesGoogle Cloud Platform。而常见的PaaS平台包括:Heroku等解决方案。

同时,通过使用诸如Amazon Relational Database Service(RDS)之类的托管数据库服务,您不必考虑数据库的升级、以及安全补丁的安装。而使用诸如Amazon Simple Notification Service(SNS,)之类的通知服务,您将不必自行构建发送电子邮件或短信等服务。

此外,通过将应用程序部署到Heroku平台上,您的应用程序将随着使用量的增加,而能够实现水平方向和垂直方向的自动扩展

原文标题:Productivity Tools and Practices for Software Engineers and Tech Companies,作者:Tyler Hawkins