2012-10-02 24 views
5

私はJavascript + BackboneJS(MVCフレームワーク)+ RequireJSフレームワークで作業していますが、この質問は多少一般的です。依存性注入対管理依存関係対グローバルオブジェクト

はしばらくの間、これについての私の頭をラッキングされていると私は

私がバックボーンに、あなたのビューは、伝統的なビューとコントローラの組み合わせであることを説明することから始めましょう、とあなたのHTMLテンプレートは、伝統的なMVCのビューです正しい/実践的なアプローチが何であるべきかは不明です。

多くのコードに依存するユーザー設定(ユ​​ニットシステム、言語選択など)を含むUserオブジェクトがあります。

私のビューの中には、テンプレートを使わずに(マッピングやグラフ作成ライブラリのようなサードパーティ製のライブラリを使用して)ほとんどの作業を行うものがあり、Userオブジェクトに依存してユニット変換、例えば。私は現在、RequireJSを使用して、カプセル化をあまり重くせずにその依存関係を管理しています。

私のビューの中には、自分自身がほとんど仕事をしていないものがあり、モデルデータをテンプレートエンジン/テンプレートに渡すだけで作業を行い、単位変換などのUserオブジェクトに依存します。この依存関係をテンプレートに渡す唯一の方法は、テンプレートにモデルを挿入し、モデルをテンプレートエンジンに渡すことです。

私の質問は、このような広く必要とされる依存関係をどのように最善に処理するかです。 - どこでもアクセス可能なApp-wide参照/グローバルオブジェクトを作成しますか? (YUK) - 一般的には、具体的なオブジェクトではなくクラス/オブジェクト定義の管理依存ロードを使用することが推奨されていますが、RequireJSの管理依存関係を使用します。 - または、依存関係インジェクションを使用して、それを必要とするすべてのものにその依存関係を手動で渡しますか?

答えて

4

純粋に技術的な観点から言えば、私は、変更可能なグローバル(グローバル変数)は、特にjavascriptでは危険で間違っていると主張します。特に、javascriptは非同期に実行されるコードの部分でいっぱいです。 addSomeStuffToLoggedinUser()が非同期にどこかに実行された場合(最初の1が終了すると例えば、それは、AJAX呼び出しを行い、その後、別のAJAX呼び出し)

window.loggedinuser = Users.get("Paul"); 
addSomeStuffToLoggedinUser(); 
window.loggedinuser = Users.get("Sam"); 
doSomeOtherStuffToLoggedinUser(); 

、それは非常によく(新しいloggedinuserにコンテンツを追加することができる:次のコードを考えてみましょう"Sam")、それが2番目のajax呼び出しに到達する頃に。明らかにあなたが望むものではありません。

私は、関数から関数、広告の無限まで、常に私たちが手を携えているユーザーオブジェクトを持っていることを支持しています。

個人的には、これらの2つの邪悪のどちらかを選択する必要がありますが、おそらく私が原子力発電所などを建設していない限り、「まったく変わることはほとんどありません。だから、私は、何らかの理由でいくつかのコールが非常に遅く実行されると、あるユーザがログアウトして、もう一方のユーザが何かにログインしてしまうというリスクを冒して、ログインしたユーザを私のアプリケーションでグローバルに利用できるようにする傾向があります奇妙なことが起こるかもしれない。 (そして再び、流星が私のアプリをホストするデータセンターにクラッシュした場合、何か不思議なことが起きるかもしれません...私はそれに対しても保護しません)。実際には、可能な解決策は、誰かがログアウトするとすぐにアプリ全体をリロードすることです。

だから、あなたのアプリに依存していると思います。それが良いになり(とあなたはまだいくつかのオブジェクト指向のカルマポイントを取得しているようにあなたが感じさせる)ことの一つは、いくつかの名前空間シングルトンであなたのデータを非表示にすることです:

doSomethingCoolWith(window.loggedinuser); 

もののの代わりに

var myuser = MyApp.domain.LoggedinDomain.getLoggedinUser(); 
doSomethingCoolWith(myuser); 

最終的にはほとんど同じことです...

+0

遅延を使って非同期に変更される可能性のあるグローバルの前に座って、この問題を緩和するための素晴らしいパターンを見つけることができます –

1

あなたは既にあなた自身の質問に答えてくれたと思いますが、誰かがあなたのためにそれを言うことを望みます:)DIを使用しますが、あなたはそれを参照する必要があるのでとにかくそれです。

1

TDDアプローチを考慮すると、これをどのようにテストしますか? DIは新しいプロジェクトには最適ですが、JSでは、テスト時に具体的なグローバル依存関係を処理するための柔軟なオプションを提供します。つまり、コンテキスト構築です。ヤフーは、すべてのモジュールが疎結合であり、互いに依存していないモジュールパターンをレイアウトしましたが、グローバルコンテキストを持つことは問題ありませんでした。そのグローバルなコンテキストは、常に再利用されるものに対して、あなたのアプリケーション構築をより実用的にすることができます。そのことを賢明に/控えめに適用する必要があるだけで、ダイナミックなものについては非常に強力なケースが必要です。