1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

JSで関数の処理から本質的でない処理を分離するProxyパターン

Last updated at Posted at 2020-09-27

どのような言語であり汎用的な関数の設計は
SOLID原則の単一責任の原則に基づいたほうがいいと思っています。

ただ、ビジネスロジックが入り込むと特定の処理に対し、ログやメール送信するなど
いわゆる付随する組み合わせ(Compound)な処理になっていきます。
すると、本質的な処理から付随した処理を分離しづらくなっていきます。

このようなオブジェクト指向ではうまく分離できない特徴(クラス間を横断 (cross-cutting) するような機能)をアスペクトと呼びます。

JavaScriptでは関数に対してProxyを使うことで体系的に本質でない処理を関数から分離することが出来ます。

参考:handler.apply()


// 単体テストするのはこっち(本質的な処理)
function sum(a, b) {
  return a + b
}

const handler = {
  // ロギング、メール送信などの処理を分離する
  apply: function(target, thisArg, argumentsList) {

    // 実行前にログを残す
    console.log(`args: ${argumentsList}`)

    // 引数をそのまま渡す
    const result = target(...argumentsList)

    // 結果のログや付随するメール送信などの処理など
    console.log(`result: ${result}`)

    return result
  }
}

const wrapSum = new Proxy(sum, handler)
wrapSum(1, 2)

次のように書いても同じやんと言われたらそうなんですけど、
Proxyのほうが体系的に書けるのがいいのかなと思います。


// 単体テストするのはこっち(本質的な処理)
function sum(a, b) {
  return a + b
}

function wrapSum(target, ...argumentsList) {

  // 実行前にログを残す
  console.log(`args: ${argumentsList}`)

  // 引数をそのまま渡す
  const result = target(...argumentsList)

  // 結果のログや付随するメール送信などの処理など
  console.log(`result: ${result}`)

  return result
}

wrapSum(sum, 1, 2)
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?