devlog

【Node.js】クロージャで builder を実装する

2023-05-22

こんにちは。Node.js の話です。
クロージャで builder パターンを組んでみました。あまり見かけないと思うのでメモ書きです。

動機

フロントエンドで React を使っていると、class を書く機会がほとんどありません。
React のエコシステムのおかげですし Redux や Recoil が状態を保持してくれるおかげでもあります。

Node.js ではそうしたものがありません。なので私は class ベースでコードを書いてしまうことが多いのですが、これをフロントエンドと同じように function ベースに置き換えられないかなあと思いました。

クロージャ

JavaScript でクロージャは次のように書きます。

const messageRepeater = (message: string) => { let state = message; return function () { state += message; console.log(state); } } const repeat = messageRepeater('something') repeat() // somethingsomething repeat() // somethingsomethingsomething repeat() // somethingsomethingsomethingsomething

something がどんどん連なっていきます。messageRepeater 内の変数 state が保持されており、repeat() する度に値が書き換わってます。state はまるで class の instance property のようです。

クロージャで builder を実装する

builder pattern を実装してみました。

type Memo = { name: (name: string) => Memo; description: (description: string) => Memo; getState: () => any; } const createMemo = () => { const state = { name: '', description: '', } const methods: Memo = { getState: () => { return state }, name: (name) => { state.name = name; return methods }, description: (description) => { state.description = description; return methods } } return methods } const memo = createMemo() memo .name('今日の天気') .description('晴れのち曇り') console.log(memo.getState()) // { name: '今日の天気', description: '晴れのち曇り' }

createMemo() で memo オブジェクトを作ります。memo オブジェクトには name() や description() というメソッドもどきがあり、繋げて書けます。memo オブジェクトの getState() を呼ぶと保持しているデータを取得できます。

ポイントは createMemo 内の methods という変数です。builder pattern なのでオブジェクト自身を返せるようにせねばなりません。そのため、わざと methods という変数を定義し自身を返せるようにしてます。

素直に class で書いたほうが良い?

実のところ class で書くよりもコード量が多くなってしまいました。また、オブジェクトに直接メソッドを生やしているため、createMemo() をする度にメソッド分のメモリが確保されます。

特別な理由がなければ素直に class を使った方がいいです。

  • 作成日
    2023-05-22
  • 更新日
    2023-05-22