JavaScript中的領域驅動設計

banq發表於2018-12-30

DDD為你的JavaScript混亂帶來秩序。
我不會把自己當作JavaScript開發人員,我總是開玩笑說這是一種我從未打算學習的語言。它現在如此普遍,它剛剛發生。我經歷了享受它和鄙視它的階段。但是透過愛的高峰和低谷並不是很討厭。一個問題仍然存在:如果我要成為一名優秀的JS開發人員並編寫函式性JavaScript,那麼我如何以使用一種合適的領域模型的方式編寫程式碼?

在傳統的OO語言中,例如Java,C#,甚至Go實際上,編寫圍繞領域設計構建的程式碼很容易。你有Class類,這些類很大並​​且能做很多事情。當然,你通常在JavaScript中會像躲避瘟疫一樣避免這種情況。

但是,我的程式碼似乎總是看起來像這樣:

const { getUser, removeUser } = require('services/user');
const { sendEmail } = require('helpers/email');
const { pushNotification } = require('helpers/notifications');
const { removeFilesByUserId } = require('services/files');
const removeUserHandler = await (userId) => {
  const message = 'Your account has been deleted';
  try {
    const user = await getUser(userId);
    await removeUser(userId);
    await sendEmail(userId, message);
    await pushNotification(userId, message);
  } catch (e) {
    console.error(e);
    sendLogs('removeUserHandler', e);
  };
  return true;
};


看起來沒問題吧?當然!這裡設計沒有大問題。但是,如果你有一個完全由這樣的檔案構成的大型程式碼庫,換句話說,目錄中充滿了模糊分組的“服務”,單獨匯出和匯入單個函式,通常含糊不清,並且在閱讀時通常不屬於某個域程式碼,它可以很快地感覺到你正在處理一個大泥球,而不是一個架構良好的軟體應用程式。

我不想回到類和傳統的封裝。在學習'functional way 之後,這感覺就像退後一步。但是,越來越多,我發現JavaScript專案難以閱讀,支離破碎。我到處都看到了這個!看起來JS專案幾乎沒有設計或架構似乎很常見。我已經準備好把JS扔進垃圾桶並轉投到Golang。

直到我的一位工程師將一個新功能放入我們最嘈雜的程式碼庫之一,這引起了我的注意。

ScheduledJobs.run(jobId);
const job = await ScheduledJobs.get(jobId);


這要做成一個類嗎?當然不是:

const run = (jobId) => {};
const stop = (jobId) => {};
const pause = (jobId) => {};
const get = (jobId) => {};
module.exports = {
 run,
 stop,
 pause,
 get,
};


整個程式碼非瑣碎,其實沒有javascript更重要概念,模組,模組其實類似“類"或聚合,是一種相似功能的聚合而已。重構程式碼如下,加入模組概念:


const UserModel = require('models/user');
const EmailService = require('services/email');
const NotificationService = require('services/notification');
const FileModel = require('models/file');
const Logger = require('services/logger');
const removeUserHandler = await (userId) => {
  const message = 'Your account has been deleted';
  try {
    const user = await UserModel.getUser(userId);
    await UserModel.removeUser(userId);
    await EmailService.send(userId, message);
    await NotificationService.push(userId, message);
    return true;
  } catch (e) {
    console.error(e);
    Logger.send('removeUserHandler', e);
  };
  return true;
};


將函式進行分組形成物件,以物件為中心編碼,這種模式比處理大量一個個未分組的函式呼叫能更好地傳達了目的。我發現它讓程式碼更容易理解,這段程式碼適合指明大局的指標。
 

相關文章