簡體   English   中英

純 function 應該如何讀取配置文件或打開數據庫?

[英]How should a pure function read a config file or open a database?

通常我的函數需要來自配置文件或數據庫的數據。 我希望盡可能地使用純函數和可以進行單元測試的東西。

我不知道如何正確地做到這一點,因為我沒有 CS 學位。 我可以看到的選項是:

示例 1:

function myFunc(p1, p2, db, configFile) { ... }

但這意味着調用myFunc()的所有其他函數也需要具有db, configFile作為 arguments。

示例 2:

function myFunc(p1, p2) { 
  const config = readConfig();
  dbConn = openDb();    
  ...
}

我想這使單元測試變得不可能?

示例 3:

const struct = {
  config: readConfig(),
  dbConn: openDb(),
  ...
};

function myFunc(p1, p2, struct) { ... }

這有不利的一面,當其他函數數據也存儲在這個全局struct中時,每個 function 可以訪問超出他們需要的內容。

問題

還有其他可能性嗎? 推薦的方法是什么?

像這樣定義myFunc()以保持其純凈:

function myFunc(p1, p2, readConfig, openDb) { ... }

並在封閉的 scope 中調用它

// other code here

{
  const config = readConfig();
  const dbConn = openDb();
  myFunc(p1, p2, readConfig, openDb);
}

// other code here
// config and dbConn isn't available here

一個 PoC:

 function func(a, b) { console.log(a); console.log(b); } const a = undefined; const b = undefined; { const a = 'private1'; const b = 'private2'; func(a, b); } console.log(a); console.log(b);

我認為您可以在這里使用依賴注入。 像這樣的東西:

function readConfig() { 
 // returns real config
}
function openDb() {
 // return real db connection
}
function readConfigMock() { 
 // returns mock config
}
function openDbMock() {
 // return mock db connection
}
function myFuncBuilder(readConfigFn, openDbFn) { 
  return function(p1, p2) {
      // can use readConfigFn everywhere because of closure
      const config = readConfigFn();
      dbConn = openDbFn();    
      ...
  }
}
const myFunc = myFuncBuilder(readConfig, openDb);

// no need to know about openDb and readConfig
function topFunc() {
  myFunc(p1, p2);
}

// code
const myFunc = myFuncBuilder(readConfig, openDb);

// test
const myFunc = myFuncBuilder(readConfigMock, openDbMock);

訣竅是將 function 作為參數傳遞。 此外,還有稱為myFuncBuilder的高階 function(返回函數的函數)。 此 function 基於 2 個 arguments 構建myFunc - 用於 db 連接的 function 和用於 Cconfig 的 ZC1C42145268E68A9F14D

因此,您可以輕松地創建readConfigopenDb的模擬以進行測試。

PS 此外,函數式編程范式教我們在這種情況下使用 IO 單子。 但是在 JS/TS 中使用 monad 的學習曲線非常陡峭。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM