web-dev-qa-db-ja.com

JavaScriptでの依存性注入を必要とするモジュール

最近、私の心に疑問が浮かびました。

Javascriptの方法は、従来のソフトウェア開発で優れていると考えられているほとんどすべてに反していますか?

このステートメントに関連する一連の質問/観察がありますが、StackExchangeの形式を尊重するために、それらを異なる質問に分割した方がよいでしょう。

必要なモジュール

現在、標準のJavaScriptコードは次のようになっています。

const someModule = require('./someModule')

module.exports = function doSomethingWithRequest() {
  // do stuff
  someModule.someFunc()
  // do other stuff
}

メリット

  • カプセル化:モジュールはスタンドアロンで動作し、その機能を実行するために必要なすべてを知っています。
  • 着色料として、クライアントがモジュールを使用する方が簡単です。

短所

  • テスト性の低下:これはDIを使用しない場合の標準ですが、Javscriptなどの動的言語では、 mockery または rewire などのモジュールによって回避できます*。
  • それは確かに [〜#〜] dip [〜#〜] に違反しています-依存性注入と混同しないでください。 -具象モジュールしかインポートできないため。
  • [〜#〜] ocp [〜#〜] に違反している可能性があります。たとえば、ファイルシステムに(fsモジュールを介して)書き込むログモジュールがあるとします。このログモジュールを拡張してネットワークに送信する場合、非常に困難になります。

*これは、ほとんどがユーザーランドで実装されているため、CommonJSまたはAMDモジュールでも動作する可能性があります。ただし、これがES6のimport構文でどのように可能になるかはわかりません。

依存性注入

依存性注入を使用すると、次のようになります。

module.exports = function doSomethingWithRequest(someModule) {
  // do stuff
  someModule.someFunc()
  // do other stuff
}

メリット

  • テスト性の向上:ES6構文を使用する場合でも、someModuleをスタブ/モックするのが簡単になりました。
  • DIPを尊重するのは可能ですが、クライアントモジュールはまだインターフェイスではなく実装にプログラムできるため、必ずしもそうとは限りません。

短所

  • カプセル化の失敗:残っている主な質問は次のとおりです:

    では、依存関係を作成/要求するのは誰ですか?

  • モジュールのすべてのクライアントでそれを行うのは非常に [〜#〜] wet [〜#〜] のようです。
  • 実際のプロジェクトで実現するためには、おそらくDIコンテナを使用する必要があります。

だから、ここでの本当の質問は:

Javascript開発者が最初のアプローチに傾く傾向があるのはなぜですか?

これは単に「Javascriptの方法」ですか?

私自身、ほとんどの場合、このようなコードを記述しています。私はモックライブラリを使用したテストセットアップの公平なシェアを持っていますが、それは常にそうすることは一種の間違っていると感じました。

何か不足していますか?

26

私は主にPHPプログラマーですが、過去1年ほどの間4つのJavaScriptチームと連絡を取り合っています。

オブジェクト指向のプログラマーとしては、依存性注入の原則が最良の方法のように思われますが、JSの開発者からはそうでないと言われてきました。 JSはまったく別の世界です。

JavaScriptを使用すると、非常に単純な手法を使用してあらゆるものに簡単にパッチを適用できるため、JavaScript開発者は、大規模なJavaScriptアプリケーションの構築方法に別のテクノロジーを採用する方法を学びました。これらのほとんどは、自己完結型モジュールのセットとしてビルドされ、パブリックエクスポートを通じて機能を公開し、依存する関数を他のユーザーが書き換えられないようにモジュールの内部を隠します。

通常のアプローチは通常、コンストラクターをこれまでに公開せずに、ファクトリラッパーを使用したオブジェクトの構築を公開することです。まったく同じ理由で、オブジェクトへのアクセス権をユーザーに付与すると、直接インスタンス化できます何でも変更できます。

モジュラー設計を利用することで、機能することを期待している関数をいじるのを他の人に拒否しますが、必要なファイルのパブリックAPIである作成したAPIを介して、モジュールをテストすることができます。

6
Andy