在如今全球疫情持續蔓延的情況下,人們往往希望透過各種生產力的增強方式,來替代當前無法面對面開展高效協作的狀況。在本文中,我們將和您討論五種有助於軟體工程師和技術公司提高工作效率的實用方式,其中包括:設計系統(Design systems)、程式碼查詢器(code linters),程式碼格式工具(code formatters)、持續整合(continuous integration)、以及IaaS/PaaS平臺(IaaS/PaaS providers)。它們能夠幫助您在不犧牲軟體產品質量的情況下,加快整個開發週期和交付程序。
設計系統
設計系統主要包含了各種設計模式、使用指南、文件、所有權模型、溝通方法、以及產品路線圖等。我們可以簡單地把它理解為一個根據可重用的構建塊(building blocks),來建立某個產品的元件庫。此處的構建塊主要包括:圖示生成器(avatars)、標誌、按鈕、下拉選單、輸入表單、圖示、連結、模式、進度指示器、以及工具提示等元件。就像樂高積木一樣,這些元件可以被組合起來,以建立應用程式必需的所有頁面和功能。
為了使軟體產品的使用者介面(UI)能夠隨著業務與功能不斷擴充套件,設計系統能夠給使用者帶來如下好處:
設計系統可幫助您建立一致性的UI,以便您在整個應用程式中都使用統一的構件塊元件。設計系統透過提供一種可以在任何地方實現的通用模式,以方便設計師和軟體工程師加快開發的速度,而不必花費數小時、甚至數天的時間去重構模式。您可以使用一組共享的元件,來輕鬆地在整個應用中一次性進行模式的更改。例如:如果您需要更改某個應用的按鈕樣式,那麼就無需逐個進行調整,而只需在設計系統中統一更改,以便直觀地應用到任何使用相關按鈕的地方。設計系統使您更加專注於提升使用者體驗(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配置的示例:
{ 2 "tabWidth": 2, 3 "useTabs": false, 4 "printWidth": 80, 5 "semi": false, 6 "singleQuote": true, 7 "trailingComma": "es5", 8 "quoteProps": "as-needed", 9 "jsxSingleQuote": false, 10 "jsxBracketSameLine": false, 11 "bracketSpacing": true, 12 "arrowParens": "avoid", 13 "endOfLine": "auto", 14 "proseWrap": "preserve", 15 "htmlWhitespaceSensitivity": "css" 16 }
我們來看一個例子。顯然,下面的Java程式程式碼,看上去十分雜亂無章:
function HelloWorld({greeting = "hello", greeted = '"World"', silent = false, onMouseOver,}) { 2 3 if(!greeting){return null}; 4 5 // TODO: Don't use random in render 6 let num = Math.floor (Math.random() * 1E+7).toString().replace(/\.\d+/ig, "") 7 8 return <div className='HelloWorld' title={`You are visitor number ${ num }`} onMouseOver={onMouseOver}> 9 10 <strong>{ greeting.slice( 0, 1 ).toUpperCase() + greeting.slice(1).toLowerCase() }</strong> 11 {greeting.endsWith(",") ? " " : <span style={{color: '\grey'}}>", "</span> } 12 <em> 13 { greeted } 14 </em> 15 { (silent) 16 ? "." 17 : "!"} 18 19 </div>; 20 21 }
透過使用Prettier,程式碼會變成如下的樣子:
function HelloWorld({ 2 greeting = 'hello', 3 greeted = '"World"', 4 silent = false, 5 onMouseOver, 6 }) { 7 if (!greeting) { 8 return null 9 } 10 11 // TODO: Don't use random in render 12 let num = Math.floor(Math.random() * 1e7) 13 .toString() 14 .replace(/\.\d+/gi, '') 15 16 return ( 17 <div 18 className="HelloWorld" 19 title={`You are visitor number ${num}`} 20 onMouseOver={onMouseOver} 21 > 22 <strong> 23 {greeting.slice(0, 1).toUpperCase() + greeting.slice(1).toLowerCase()} 24 </strong> 25 {greeting.endsWith(',') ? ( 26 ' ' 27 ) : ( 28 <span style={{ color: 'grey' }}>", "</span> 29 )} 30 <em>{greeted}</em> 31 {silent ? '.' : '!'} 32 </div> 33 ) 34 }
自動化測試和持續整合
隨著應用程式在複雜性和程式碼體量上的增長,我們再也無法單靠一己之力,手動測試目標應用中涉及到的所有內容。我們需要進行動作分解,透過自動化測試來完成單元測試、整合測試、端到端(E2E)測試、以及迴歸測試。
由DevOps理念帶來的持續整合(CI)實踐,則能夠確保您程式碼的主分支在理論上,一直處於可執行的狀態。為此,您可以使用Travis CI、CircleCI、GitLab CI/CD、以及Heroku CI之類的服務,來為儲存庫設定持續整合。在此基礎上,您可以透過配置CI管道,以便在每次提交後,執行檢視器和自動化測試,進而在滿足所有前續條件的基礎上,實現程式碼合併。實踐證明,相對於手動測試,自動化測試和持續整合都能夠大幅減少整個開發週期的用時。
IaaS和PaaS平臺
在如今雲服務盛行的時代,我們要學會善用基礎架構即服務(IaaS)和平臺即服務(PaaS),來管理應用的基礎架構。目前,常見的IaaS平臺包括Amazon Web Services、Google Cloud Platform。而常見的PaaS平臺包括:Heroku等解決方案。
同時,透過使用諸如Amazon Relational Database Service(RDS)之類的託管資料庫服務,您不必考慮資料庫的升級、以及安全補丁的安裝。而使用諸如Amazon Simple Notification Service(SNS,)之類的通知服務,您將不必自行構建傳送電子郵件或簡訊等服務。
此外,透過將應用程式部署到Heroku平臺上,您的應用程式將隨著使用量的增加,而能夠實現水平方向和垂直方向的自動擴充套件。