」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 掌握 Javascript 函數式程式設計

掌握 Javascript 函數式程式設計

發佈於2024-08-17
瀏覽:744

GRASP in Javascript functional programming

在軟體開發領域,設計模式是針對常見問題經過時間考驗的解決方案。
GRASP(通用責任分配軟體模式)是較少討論但同樣重要的設計模式集之一。 GRASP 的原則通常與 SOLID 原則和其他 OOP 設計模式相關。
GRASP(通用責任分配軟體模式)是一系列指南,旨在將責任分配給物件導向設計中的類別和物件。我們如何在 Javascript (Node.js) 開發中使用這些模式?當然,Javascript 支援類,這些類別本身是基於原型構建的,我們可以像在 Java 中那樣以類似的方式應用 GRASP。
然而,在我看來,GRASP 模式也可以應用於函數式程式設計。

什麼是GRASP?

九種 GRASP 模式是:

  1. 資訊專家
  2. 創作者
  3. 控制器
  4. 低耦合
  5. 高內聚力
  6. 多態性
  7. 純製造
  8. 間接
  9. 受保護的變體

資訊專家

將職責分配給擁有執行任務所需資料或知識的職能部門。在函數式程式設計中,可以透過將職責指派給具有執行任務所需的資料或上下文的函數或模組來應用此原則。

// User management module
const createUser = (name, email) => ({ name, email });

const getUserEmail = (user) => user.email;

const updateUserEmail = (user, newEmail) => ({
  ...user,
  email: newEmail,
});

const user = createUser('John Doe', '[email protected]');
console.log(getUserEmail(user));  // '[email protected]'

const updatedUser = updateUserEmail(user, '[email protected]');
console.log(getUserEmail(updatedUser));  // '[email protected]'

創作者

使用工廠函數建立複雜的資料結構或物件。在函數式程式設計中,雖然我們處理類別的方式與物件導向程式設計不同,但我們可以應用創建者原則,將創建資料結構或初始化物件的責任分配給具有必要資訊的函數或模組,並且情境。

const createUser = (name, email) => ({ name, email });

控制器

使用高階函數處理系統事件和委託任務。在函數式程式設計中,控制器通常採用函數的形式來編排系統不同部分之間的資料流和操作,確保職責明確分離。

// Example of express.js controller
const handleRequest = (req, res, userService) => {
  const user = userService.createUser(req.body.name, req.body.email);
  res.send(user);
};

低耦合

確保函數是獨立的並且僅依賴明確輸入。在函數式程式設計中,低耦合是透過設計彼此獨立運行的函數和模組來實現的,並且對其他函數或模組的內部細節的依賴最小化

const sendEmail = (emailService, email) => emailService.send(email);

高內聚力

高內聚是指模組或功能內的元素所屬的程度。在函數式程式設計中,實現高內聚意味著設計函數和模組,以便它們執行單一、明確定義的任務或密切相關的一組任務。

const createUser = (name, email) => ({ name, email });
const addUser = (users, user) => [...users, user];

const createAndAddUser = (users, name, email)=>{
  const user = createUser(name, email);
  return addUser(users, user)
}
// usage
const users = [
  { name: 'Alice', email: '[email protected]' },
  { name: 'Bob', email: '[email protected]' },
];

const newUsers = createAndAddUser(users, 'Charlie', '[email protected]');

多態性

使用高階函數和一等函數實現多態。在函數式程式設計中,多態性通常是透過高階函數、泛型函數和 Typescript
等型別系統來實現

const processPayment = (paymentMethod) => paymentMethod.process();

純製造

當不存在適當的域函數或類別時,建立不直接對應於域概念但提供必要功能的實用函數。

const log = (message) => console.log(message);

間接

函數式程式設計中的間接是指使用中間函數來管理系統不同部分之間的交互作用。 Node.js 中的一個很好的例子是中間件模式。

const withNumberFilterMiddleware = (data) => data.filter(item => !isNaN(Number(item)));

受保護的變體

函數式程式設計中受保護的變化意味著透過封裝變化的部分並確保系統的其餘部分免受這些變化的影響,創建一種能夠適應變化的設計。 在函數式程式設計中,可以透過使用抽象、不變性和封裝來應用此原則,以創建不易更改的健壯且可維護的程式碼。

const processCreditCardPayment = (amount) => {
  console.log(`Processing credit card payment of ${amount}`);
  // Credit card payment logic
};

const processPayPalPayment = (amount) => {
  console.log(`Processing PayPal payment of ${amount}`);
  // PayPal payment logic
};

const processPayment = (paymentMethod, amount) => {
  paymentMethod(amount);
};

// Use different payment methods without changing the processPayment function
processPayment(processCreditCardPayment, 100);
processPayment(processPayPalPayment, 200);

概括

正如您所看到的,GRASP 原則與許多已知的設計模式以及 SOLID 原則相關。高內聚幾乎等於單一職責原則等等。
這些原則不僅是 OOP 原則,而且是編寫架構良好的乾淨程式碼的一般原則,無論是函數式程式設計還是 OOP 程式設計。

版本聲明 本文轉載於:https://dev.to/ohanhaliuk/grasp-in-javascript-functional-programming-2jh6?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • PHP陣列鍵值異常:了解07和08的好奇情況
    PHP陣列鍵值異常:了解07和08的好奇情況
    PHP數組鍵值問題,使用07&08 在給定數月的數組中,鍵值07和08呈現令人困惑的行為時,就會出現一個不尋常的問題。運行print_r($月)返回意外結果:鍵“ 07”丟失,而鍵“ 08”分配給了9月的值。 此問題源於PHP對領先零的解釋。當一個數字帶有0(例如07或08)的前綴時,PHP將...
    程式設計 發佈於2025-07-14
  • PHP與C++函數重載處理的區別
    PHP與C++函數重載處理的區別
    作為經驗豐富的C開發人員脫離謎題,您可能會遇到功能超載的概念。這個概念雖然在C中普遍,但在PHP中構成了獨特的挑戰。讓我們深入研究PHP功能過載的複雜性,並探索其提供的可能性。 在PHP中理解php的方法在PHP中,函數超載的概念(如C等語言)不存在。函數簽名僅由其名稱定義,而與他們的參數列表無關...
    程式設計 發佈於2025-07-14
  • 圖片在Chrome中為何仍有邊框? `border: none;`無效解決方案
    圖片在Chrome中為何仍有邊框? `border: none;`無效解決方案
    在chrome 在使用Chrome and IE9中的圖像時遇到的一個頻繁的問題是圍繞圖像的持續薄薄邊框,儘管指定了圖像,儘管指定了;和“邊境:無;”在CSS中。要解決此問題,請考慮以下方法: Chrome具有忽略“ border:none; none;”的已知錯誤,風格。要解決此問題,請使用以下...
    程式設計 發佈於2025-07-14
  • 如何從Google API中檢索最新的jQuery庫?
    如何從Google API中檢索最新的jQuery庫?
    從Google APIS 問題中提供的jQuery URL是版本1.2.6。對於檢索最新版本,以前有一種使用特定版本編號的替代方法,它是使用以下語法:獲取最新版本:未壓縮)While these legacy URLs still remain in use, it is recommended ...
    程式設計 發佈於2025-07-14
  • 為什麼我在Silverlight Linq查詢中獲得“無法找到查詢模式的實現”錯誤?
    為什麼我在Silverlight Linq查詢中獲得“無法找到查詢模式的實現”錯誤?
    查詢模式實現缺失:解決“無法找到”錯誤在銀光應用程序中,嘗試使用LINQ建立錯誤的數據庫連接的嘗試,無法找到以查詢模式的實現。 ”當省略LINQ名稱空間或查詢類型缺少IEnumerable 實現時,通常會發生此錯誤。 解決問題來驗證該類型的質量是至關重要的。在此特定實例中,tblpersoon可能...
    程式設計 發佈於2025-07-14
  • PHP SimpleXML解析帶命名空間冒號的XML方法
    PHP SimpleXML解析帶命名空間冒號的XML方法
    在php 很少,請使用該限制很大,很少有很高。例如:這種技術可確保可以通過遍歷XML樹和使用兒童()方法()方法的XML樹和切換名稱空間來訪問名稱空間內的元素。
    程式設計 發佈於2025-07-14
  • 如何在Chrome中居中選擇框文本?
    如何在Chrome中居中選擇框文本?
    選擇框的文本對齊:局部chrome-inly-ly-ly-lyly solument 您可能希望將文本中心集中在選擇框中,以獲取優化的原因或提高可訪問性。但是,在CSS中的選擇元素中手動添加一個文本 - 對屬性可能無法正常工作。 初始嘗試 state)</option> < o...
    程式設計 發佈於2025-07-14
  • 如何將多種用戶類型(學生,老師和管理員)重定向到Firebase應用中的各自活動?
    如何將多種用戶類型(學生,老師和管理員)重定向到Firebase應用中的各自活動?
    Red: How to Redirect Multiple User Types to Respective ActivitiesUnderstanding the ProblemIn a Firebase-based voting app with three distinct user type...
    程式設計 發佈於2025-07-14
  • Python高效去除文本中HTML標籤方法
    Python高效去除文本中HTML標籤方法
    在Python中剝離HTML標籤,以獲取原始的文本表示Achieving Text-Only Extraction with Python's MLStripperTo streamline the stripping process, the Python standard librar...
    程式設計 發佈於2025-07-14
  • CSS強類型語言解析
    CSS強類型語言解析
    您可以通过其强度或弱输入的方式对编程语言进行分类的方式之一。在这里,“键入”意味着是否在编译时已知变量。一个例子是一个场景,将整数(1)添加到包含整数(“ 1”)的字符串: result = 1 "1";包含整数的字符串可能是由带有许多运动部件的复杂逻辑套件无意间生成的。它也可以是故意从单个真理...
    程式設計 發佈於2025-07-13
  • 為什麼我的CSS背景圖像出現?
    為什麼我的CSS背景圖像出現?
    故障排除:CSS背景圖像未出現 ,您的背景圖像儘管遵循教程說明,但您的背景圖像仍未加載。圖像和样式表位於相同的目錄中,但背景仍然是空白的白色帆布。 而不是不棄用的,您已經使用了CSS樣式: bockent {背景:封閉圖像文件名:背景圖:url(nickcage.jpg); 如果您的html,cs...
    程式設計 發佈於2025-07-13
  • 如何干淨地刪除匿名JavaScript事件處理程序?
    如何干淨地刪除匿名JavaScript事件處理程序?
    刪除匿名事件偵聽器將匿名事件偵聽器添加到元素中會提供靈活性和簡單性,但是當要刪除它們時,可以構成挑戰,而無需替換元素本身就可以替換一個問題。 element? element.addeventlistener(event,function(){/在這里工作/},false); 要解決此問題,請考...
    程式設計 發佈於2025-07-13
  • 在GO中構造SQL查詢時,如何安全地加入文本和值?
    在GO中構造SQL查詢時,如何安全地加入文本和值?
    在go中構造文本sql查詢時,在go sql queries 中,在使用conting and contement和contement consem per時,尤其是在使用integer per當per當per時,per per per當per. 在GO中實現這一目標的慣用方法是使用fmt.spr...
    程式設計 發佈於2025-07-13
  • 如何使用Depimal.parse()中的指數表示法中的數字?
    如何使用Depimal.parse()中的指數表示法中的數字?
    在嘗試使用Decimal.parse(“ 1.2345e-02”中的指數符號表示法表示的字符串時,您可能會遇到錯誤。這是因為默認解析方法無法識別指數符號。 成功解析這樣的字符串,您需要明確指定它代表浮點數。您可以使用numbersTyles.Float樣式進行此操作,如下所示:[&& && && ...
    程式設計 發佈於2025-07-13
  • 如何使用PHP將斑點(圖像)正確插入MySQL?
    如何使用PHP將斑點(圖像)正確插入MySQL?
    essue VALUES('$this->image_id','file_get_contents($tmp_image)')";This code builds a string in PHP, but the function call fil...
    程式設計 發佈於2025-07-13

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3