59

メインアプリと認証アプリのモジュールとして別々のルーターファイルを使用しています。変数(dbクライアント)をルーターに渡すための最良の方法を取得できません。私はそれをハードコーディングしたり、次のものと一緒に渡したりしたくありません:

module.exports = function(app, db) {

たぶん、シングルトンレジスタを使用するか、グローバルdb変数を使用するのが最善の方法ですか?

デザインパターンの経験は何ですか?どちらの方法が最適で、その理由は何ですか?

4

4 に答える 4

109

私は、依存性注入を使用して、物事を渡すのが最良のスタイルであることに気づきました。それは確かにあなたが持っているようなものに見えるでしょう:

// App.js
module.exports = function App() {
};

// Database.js
module.exports = function Database(configuration) {
};

// Routes.js
module.exports = function Routes(app, database) {
};

// server.js: composition root
var App = require("./App");
var Database = require("./Database");
var Routes = require("./Routes");
var dbConfig = require("./dbconfig.json");

var app = new App();
var database = new Database(dbConfig);
var routes = new Routes(app, database);

// Use routes.

これには多くの利点があります。

  • これにより、ファイルの途中で依存関係を非表示にするのではなく、システムを明確な依存関係を持つコンポーネントに分離する必要がありrequire("databaseSingleton")ますglobal.database
  • 単体テストが非常に簡単になりますRoutes。単独でテストしたい場合は、偽appのパラメーターとパラメーターを挿入して、コード自体databaseのみをテストできます。Routes
  • server.jsこれにより、すべてのオブジェクトグラフの配線が1つの場所、つまりコンポジションルート(この場合はアプリのエントリポイント)にまとめられます。これにより、システム内ですべてがどのように組み合わされているかを確認するための単一の場所が提供されます。

私が見たこれについてのより良い説明の1つは、.NETの優れた本DependencyInjectionの著者であるMarkSeemanへのインタビューです。これはJavaScript、特にNode.jsにも同様に適用されます。モジュールシステムだけでなく、従来のサービスロケーターとしてよく使用されます。require

于 2012-04-26T06:31:32.070 に答える
2

dbインスタンスや、「singleton」などのグローバルに使用する必要のあるその他のものを使用して設定ファイルを作成することをお勧めします。

たとえば、redisdbクライアントでsettings.jsがあります。

var redis = require('redis');
exports.redis = redis.createClient(6379, '127.0.0.1');

そして、他の複数のモジュールに私はそれを含めます:

var settings = require('./settings');
setting.redis.<...>

それを含めて多くの場合、私は常にdb接続のインスタンスを1つ持っています。

于 2012-04-25T13:13:08.587 に答える
1

依存性注入フレームワークを使用すると、モジュールを配線するための定型コードをすべて節約できます。

この回答には、それらのいくつかがリストされています。また、ここでより単純なDIフレームワークを構築しました。

編集:以下は、ページが変更された場合の回答からのコピーです


requireはNode.jsの依存関係を管理する方法であり、確かに直感的で効果的ですが、制限もあります。

私のアドバイスは、Node.jsで現在利用可能な依存性注入コンテナーのいくつかを見て、それらの長所/短所が何であるかを理解することです。それらのいくつかは次のとおりです。

ほんの数例を挙げると。

さて、本当の問題は、単純なものと比較して、Node.jsDIコンテナーで何を達成できるかということですrequire

長所:

  • 妥当性の向上:モジュールは依存関係を入力として受け入れます
  • 制御の反転:アプリケーションのメインコードに触れずにモジュールを配線する方法を決定します。
  • モジュールを解決するためのカスタマイズ可能なアルゴリズム:依存関係には「仮想」識別子があり、通常、ファイルシステム上のパスにバインドされていません。
  • 拡張性の向上:IoCおよび「仮想」識別子によって実現されます。
  • 可能な他の派手なもの:
    • 非同期初期化
    • モジュールのライフサイクル管理
    • DIコンテナ自体の拡張性
    • より高いレベルの抽象化(AOPなど)を簡単に実装できます

短所:

  • Node.jsの「エクスペリエンス」とは異なります。使用しrequireないと、Nodeの考え方から逸脱しているように感じます。
  • 依存関係とその実装の関係は、必ずしも明示的ではありません。依存関係は実行時に解決され、さまざまなパラメーターの影響を受ける可能性があります。コードの理解とデバッグがより困難になります
  • 起動時間が遅い
  • 成熟度(現時点):現在のソリューションはどれも現時点ではあまり人気がないため、チュートリアルもエコシステムも、バトルテストもそれほど多くありません。
  • 一部のDIコンテナーは、BrowserifyやWebpackなどのモジュールバンドラーではうまく機能しません。
于 2016-06-25T14:34:29.807 に答える
0

それは完全に時代遅れですがglobal 、スクリプトで使用できます:

 global.foo = new Foo();

別のスクリプトで:

 foo.bar();

既存の定数を使用することもできます:

 Object.foo = new Foo();

そしてここ :

 Object.foo.bar();
于 2014-02-23T16:55:11.060 に答える