摘要:如你所知,這是你在面試好萊塢電影里的一個角色后可能聽到的答復。而軟件世界里的好萊塢原則也是一樣的觀念。也稱為抽象編程對比傳統的面向對象編程來說函數式編程更優越。
這篇文章包含了幾乎所有關于提高代碼質量的內容,尤其是在構建大型應用程序時。
主要包括四個部分:
基本原則
保持整潔
保持擴展性
抽象化
本主題僅涉及原生js,關于框架(比如react和vue)的內容會在以后的文章中展現。基本原則
我想你們大多數人之前都聽說過SOLID,也就是面向對象設計里的SOLID原則。
這些原則基于面向對象設計,所以可能不適合其他編程范式。即便如此,它也涵蓋了大多數情況。
例如,SOD既可以應用于面向對象編程,也可以應用于函數式編程。
單一責任原則(SRP) 開放封閉原則(OCP) 里氏替換原則(LSP) 接口分離原則(ISP) 依賴倒置原則(DIP) 保持整潔 變量變量或許是在開發過程中最常見的術語。
命名使用語義明確的命名
// 不推薦 // 我不知道這個變量代表什么意義 const flag = true; // 推薦 const downloaded = true; const enabled = true;
使用可讀的命名
// 不推薦 // 也是沒有意義 const yyyyMMdd; // 推薦 const today;
使用語義一致的詞匯
// 不推薦 // file1 function getUserData() // file2 function fetchUserData() // file3 function getUserRecord() // file4 function getUserInfo() // 推薦 // file1 function getUserInfo() // file2 function getUserInfo() // file3 function getUserInfo() // file4 function getUserInfo()
使用可搜索的命名
// 不推薦 for(let i=0;i<5;i++) { // ... } // 推薦 const COUNT = 5; for(let i=0;i使用自解釋的命名
// 不推薦 if (!group) { return pictureCollect.list; } return getListByGroup(group, pictureCollect.list); // 推薦 const getAllList = list => list; // const getAllList = R.identity(list) if (!group) { return getAllList(pictureCollect.list); } return getListByGroup(group, pictureCollect.list);避免冗余的命名
// 不推薦 const phone = { phoneOwner: "lucifer", phoneSize: "" } // 推薦 const phone = { owner: "lucifer", size: "" }好代碼,不撒謊
程序從不說謊,但注釋(也包括名稱)可能會。類型推薦使用 const
控制流使用promise方法而不是callback(回調函數)
異步/等待也是非常強大的。分支使用短路表達式或默認值
// 不推薦 function downloadFile({_filename, _encoding}) { let filename = "untitled.txt"; let encoding = "utf-8" if (filename) { filename = _filename; } if (encoding) { encoding = _encoding; } // .... } // 推薦 function downloadFile({filename = "untitled.txt", _encoding}) { const encoding = _encoding || "utf-8"; // .... }使用策略或多態性(開放封閉原則)
使用責任鏈(開放封閉原則)
將其分解成不同的功能(單一責任原則)
封裝條件
// 不推薦 if (number === 0 && (1 / number) === -Infinity) // 推薦 function isNegativeZero(number) { return number === 0 && (1 / number) === -Infinity } if (isNegativeZero(number))避免不必要的條件
表達使用迭代器而不是循環
在特定環境下遞歸表現的更好。函數 參數盡量要少 使用純函數 相比于命令式,函數式更好 小心在全局作用域中的函數(包括在他們原型對象上的方法) one level of abstraction 只做一件事情(單一責任原則) write less 調用者和被調用者位置應該盡量接近 報錯永遠不要對報錯不做處理
// 不推薦 const logger = console.log.bind(console) fetch("http://www.test.com") .then(notifyUser) .catch(logger) // 推薦 fetch("http://www.test.com") .then(notifyUser) .catch(err => { // 你可以全做,也可以選一個 console.error(err) notifyUser(err) sendErrToServer(err) })打印、存儲、通知用戶或將其發送到遠程服務器測試一步一測試
格式美觀
一致
注釋注釋讓人難以理解的關鍵部分
刪除注釋代碼
注釋必要的信息
create, ltime etc避免繪圖注釋
根據代碼意義注釋,不要說謊
注釋應與相關代碼位置一致
相比于注釋,一個語義明確的命名更好
// 不推薦 // means the date of the today const yyyyMMdd; // 推薦 const today;保持擴展性 增強 好萊塢原則我一直很欣賞好萊塢原則這個名稱的巧妙。這個原則的本質是“不要給我打電話,我會打給你”。如你所知,這是你在面試好萊塢電影里的一個角色后可能聽到的答復。而軟件世界里的好萊塢原則也是一樣的觀念。其目的是注意要聰明的構造和實現你的依賴關系。
例如:
import a from "../../a.js" import b from "../../../b.js" import a from "../c.js" function app() { return { start() { a.start(); b.start(); c.start(); console.log("app stared~") } } }我們編寫的代碼直接依賴于a、b和c。當它們中的任何一個改變它的api或位置時,你必須跟著變動代碼。
var { decorator } = require("./decorator.public.js"); function app({a, b, c}) { return { start() { console.log("app stared~") } } } // enhance // = IOC + decorator decorator(app);if we use enhance, which implemented by IoC and decorator.
如果我們使用通過Ioc和裝飾器實現的增強技術,
可以使得應用程序易于測試和擴展。.裝飾器可能就像這樣:
// 為了簡單的目的 import a from "../../a.js" import b from "../../../b.js" import a from "../c.js" function decorator(app) { return app({a, b, c}) }這很簡單,但完全不同。
app的參數道出了真相
從依賴項中解耦
而且我們可以改變app的行為.
function a() {console.log("a")} var _a = a; a = function() { _a(); console.log("hello decorator") } a(); // a // hello decorator更優雅的方式:
function a() {console.log("a")} function dec() {onsole.log("hello decorator")} compose(dec, a)抽象化軟件開發的關鍵是找出變量和變量。
然后對不變部分進行編程,使變量的影響在它的控制之下。
也稱為抽象編程.
對比傳統的面向對象編程(OOP)來說,函數式編程(FP)更優越。
借助“無數據樣式”(即“pointfree”)的幫助,您可以將細節與邏輯分離開來。
所以你可以多帶帶留下細節,讓邏輯變得純粹。我想再強調一點,那就是人們有時會說,沒有抽象概念總比錯誤的抽象好。這實際上意味著錯誤抽象的代價非常高,所以要小心。我認為這有時會被誤解。這并不意味著您應該沒有抽象概念。 這只意味著你必須非常小心。 -- Malte Ubl在JSConf澳大利亞演講。我們必須善于發現正確的抽象。
只有這樣,您才能編寫可重用的、可管理的和可擴展的代碼。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/108118.html
摘要:高內聚低耦合高內聚低耦合一直是軟件設計領域里亙古不變的話題,重構的目標是提高代碼的內聚性,降低各功能間的耦合程度,降低后期維護成本,特別是寫業務代碼,這一點相當重要。0x00 前言 我是一名來自螞蟻金服-保險事業群的前端工程師,在一線大廠的業務部門寫代碼,非常辛苦但也非常充實。業務代碼不同于框架代碼、個人項目或者開源項目,它的特點在于邏輯復雜、前后依賴多、可復用性差、迭代周期短,今天辛辛苦苦...
摘要:這樣優化后我們最多進行次判斷即可,大大提高了代碼的性能。表達式的值具有離散性, 個人博客,點擊查看目錄,喜歡可以關注一下. 1.從[]==![]為true來剖析JavaScript各種蛋疼的類型轉換 2.吹毛求疵的追求優雅高性能JavaScript 李小龍說過:天下武功,無堅不摧,唯快不破.(真的說過嗎?)我想說的是:世間網站,完美體驗,唯快不破.(這個我承認我說過.) showImg...
摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復雜性。寫一個符合規范并可配合使用的寫一個符合規范并可配合使用的理解的工作原理采用回調函數來處理異步編程。 JavaScript怎么使用循環代替(異步)遞歸 問題描述 在開發過程中,遇到一個需求:在系統初始化時通過http獲取一個第三方服務器端的列表,第三方服務器提供了一個接口,可通過...
閱讀 781·2023-04-25 16:55
閱讀 2818·2021-10-11 10:59
閱讀 2081·2021-09-09 11:38
閱讀 1795·2021-09-03 10:40
閱讀 1493·2019-08-30 15:52
閱讀 1133·2019-08-30 15:52
閱讀 964·2019-08-29 15:33
閱讀 3505·2019-08-29 11:26