オブジェクト指向、DIとService Locatorの違いを教えて4
■ このスレッドは過去ログ倉庫に格納されています
■ オブジェクト指向・デザインパターン(有用)
わかり易い例
class Dog extends Animal
class Cat extends Animal
■ DI(ゴミ)
DIとは?・・・オブジェクト指向の依存関係を"ひとまとめに"定義する部分と、それを利用するために
オブジェクトを直接newするのではなく、DIコンテナにnewしてもらうパターン
http://kakutani.com/trans/fowler/injection.html
> Dependency Injection の形式
> Dependency Injection の基本的な考え方は、独立したオブジェクトを
> Assembler(組み立て係)として用意し、 MovieFinder インタフェースの実装を
> MovieLister クラスのフィールドへ適切に設定させるというものだ。
> 依存関係は図2のようになる。
前スレ
オブジェクト指向とは 分かりやすく教えてくれ
https://medaka.5ch.net/test/read.cgi/prog/1521869966/
オブジェクト指向を分かりやすく例えて教えてくれ 2
https://medaka.5ch.net/test/read.cgi/prog/1525660302/
オブジェクト指向とDIを分かりやすく例えて教えてくれ 3
https://medaka.5ch.net/test/read.cgi/prog/1526733859/ >>177
じゃあ>>140への回答はコンストラクタで設定すれば良い、でFAだな
コンストラクタで渡せばDIコンテナなんて不要なことすら分からないなんてお前はホントにアホだなw DIの使われ方を見ると依存関係がどうこうというより、
クラスに対する設定を記述しているだけな気がするな なんでアンチは自分が考えたオレオレDIをファウラーのDIみたいに言うの?
もっと提唱者に敬意を払うべきでは? オブジェクト指向にしろDIにしろ
実際に困ったことありました→ある手法を使ったことでこんなに便利になりました
ってことが明確にわかる実例がないから悪いんだよね
xmlのこのクソなげえ設定ファイルが必要ですがそれを補って有り余る程DIには利点があり
こんなに便利になりましたってのが1ミリもわからない
そこら編を死ぬほど詳しく書いた本とか売れそうな気もするんだけど誰も書かないな >>178
> じゃあ>>140への回答はコンストラクタで設定すれば良い、でFAだな
コンストラクタで設定するのはnew相当を行うときだ。
質問はnew相当のことをどうやって行うかだ
俺なら、インスタンスの作成をするにはどうすればいい?の答えに
new演算子を使用すると答えるが、
お前は、コンストラクタで設定すればいいって答えるのか?
回答が意味不明だぞ >>181
実際は新しい言葉作ってバカなPGを手玉に取ってお金を集めちゃう商売だからそんな資料は作れないよ >>183
それが大事だよね
ここのドカタが何言ってるかよりも >>181
デザインパターンのカタログは、書式がしっかりしていて
ちゃんとどういう問題を解決するのか?を書く項目があるぞ
https://qiita.com/ndxbn/items/6557646c5398e06aea49#%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3-is-%E3%81%AA%E3%81%AB
> パターン名
> そのパターンが解決する問題
> そのパターンが如何にして問題を解決するかの、解法
> 結果発生する、トレードオフ
それに対してDIは解決する問題がなくて、
依存関係を分離しておけば、将来なにかの役に立つでしょ?になってる >>182
もともとは>>138の
> MovieLister から ServiceLocator への参照が発生するのがサービスアロケータだろ
に対して、>>140が参照持たないためにはnewするしかないって言ってる
で、その回答として
コンストラクタで渡せばMovieLister から ServiceLocator への参照が発生しません
って言ってるわけ。何が意味不明なの? >>187
> コンストラクタで渡せばMovieLister から ServiceLocator への参照が発生しません
だからその場合、どうやってインスタンスを作成するのかって話をしてるんだが?
お前はインスタンス作成後の話しかしてねーじゃねーか
わざとか?
ちゃんと話を読め↓
> ないけど、事実上そうだよ。
> でないとサービスロケーターになってしまう
>
> DIパターンにおけるインスタンスを生成するオブジェクト(通常DIコンテナ)に
> 依存せずにインスタンスを生成するには、上の層でインスタンスを生成してもらわないといけない
> 上の層っていうのはフレームワークに隠蔽されたアクションに相当する処理の開始部分
>
> 「DIパターンにおけるインスタンスを生成するオブジェクト」を上の層以外の
> 部分で使うことは、それに依存してしまうことになってしまい、
> それは事実上サービスロケーターと同じことになる >>191
サービスアロケータになってしまうと言うのは貴方の感想であって
ファウラーの定義では参照がなかったらサービスアロケータではありません >>189
いいのか、その話をして?
依存関係を一箇所に書くんじゃなくて、
今は各クラスにアノテーションとして書きましょう
に変わったって言いたいんだろう? >>192
残念ながら事実だよ。
手動でnewしてしまうと、依存関係の定義情報が使用できない >>194
なんでファウラーの定義を離れて勝手なオレオレDIの話をするの? >>195-196
はい? DIの話なんかしてませんよ?
DIにならないって話をしてるんですが
この場合、DIの定義である↓を満たせない
> Dependency Injection の基本的な考え方は、独立したオブジェクトを
> Assembler(組み立て係)として用意し、 MovieFinder インタフェースの実装を
> MovieLister クラスのフィールドへ適切に設定させるというものだ。
DIじゃない方を使いましょうって言ってるんでしょ? DIコンテナが無くてもDIできる。
ただしメンテナンス性が大きく下がる >>199
DIコンテナが無くてもDIできる、でFAね
良かった良かった そりゃオレオレDIコンテナを作ればできるだろうけど、
こいつ何を言ってるんだろう? ファウラーのDIをドカタが勝手に独自解釈してるから正しただけだが?
提唱者には敬意を払わないとね >>201
オレオレDIコンテナって何それ?
ファウラーの定義に出てきますか? そうだ!Factoryが生成するインスタンスのClassを、設定ファイルに記述するようにしたらいいんじゃないかな? DIコンテナもxml設定ファイルもウンコ言語Javaが産んだドカタ文化だろ
Javaのゴミさを理由にDIを貶めてんじゃねーよ services.AddTransient<IUnko>(c =>
new LogDecorator(
new TransactionScopeDecorator(
new IOValidationDecorator(
new UnkoImpl(c => c.GetService<IDepend1>(),
c.GetService<IDepend2>(),
...
))));
DIコンテナを使うとこんな馬鹿みたいな定義がずらずらと並んでしまう
これはもはやXMLより酷い
こんなんならファクトリークラスとして責務分割したほうがマシ
DIコンテナはおぞましく巨大な泥団子そのもの
オブジェクト指向信者が使っていいものじゃない >>209
Factoryで責務分割すると、どういうこーどになるの? >>211
> Factoryで責務分割すると、どういうこーどになるの?
違う違う。Factoryで責務分割するのではない
依存関係を外部から注入するから、こういう結果になるということなんだから
依存関係を埋め込むことで、シンプルになる。
依存関係を埋め込んでるだけでSOLID原則を破るわけではないので問題はない
(SOLID原則には依存関係を埋め込んではいけないなどという原則は無い)
またFactoryを使うなって話でもない。設計上必要な場所にはFactoryを使う
単に依存関係を分離するためにDIだかFactoryだかを使わないって話 スマンちょっと研究したらDecoratorふつうに出来たわ
DIコンテナは神。ファクトリーはゴミという結果になってしまった >>216
どうやって? DIではDecoratorはできないはずだけど? >>219
DIは依存関係を注入するだけだからだよ 依存関係注入が悪い翻訳だからね
加えて
コンポーネントはパラメーターで渡そう
コンポーネント組立は設定ファイルで
いや属性でやるだろ
とか議論の軸も整理されてない ファウラーのDIが、DIの正しい定義だって
言ってるのにそれを無視するからこうなるんだよ
ファウラーは依存関係を分離するために
依存関係を注入する側の仕組みをどうするかの話をしてるのに
依存関係が注入される側の仕組みの方を見て
注入する側の仕組みは何でも構わない、変数の型をインターフェースにしておいて、
内部でnewしなければなんでもDIだって言ってるから意味不明なことになる
議論の筋の整理のレベルじゃなくて、間違った理解をしてる >>223
ファウラーは依存関係を注入する側の仕組みについてなんて定義してるの?
って聞いてみたけど、また引用じゃなくて独自解釈を垂れるんだろうな...w >>224
書いてあるやん。
「Assemblerが適切に設定させる」というように設定部分の話をしてる
クラスにインターフェースの変数を用意してコンストラクタで渡してもらうなんて話はしてない
http://kakutani.com/trans/fowler/injection.html
> Dependency Injection の形式
> Dependency Injection の基本的な考え方は、独立したオブジェクトを
> Assembler(組み立て係)として用意し、 MovieFinder インタフェースの実装を
> MovieLister クラスのフィールドへ適切に設定させるというものだ。
> 依存関係は図2のようになる。 依存関係を解決する側はなんでもいい
ファクトリーでもいいし
DIコンテナでもいい(というかこれはモロにファクトリー)
貧者のDIでもいいし
メインで初期化でもいい
あくまでオプション Dependency Injection の基本的な考え方は
って書いてるのに、オプションとか意味不明
基本的な考え方ぐらい理解しましょうや 工場(ファクトリー)に鉄製品を作る機能をもたせたものを製鉄所というのであって、
工場だったら必ず製鉄所になるわけじゃない。
依存関係を解決する機能をもたせたものがDIなのであって
FactoryだったらかならずDIコンテナになるわけじゃない もうさ、用語として組み込み系で使いづらいんだよなぁ >>227
基本的な考え方は依存するクラスをインターフェースに置き換えて外部から与えましょうってだけ
ここまでがDIの本質
でもそうすると規模が大きくなった時に外部から与える処理自体が複雑になってくるよね
って副次的な課題に対しての解決策が幾つかあって
それがファクトリーやDIコンテナや貧者のDI
DIを語る上ではこれらは必須ではない
という意味でのオプション >>230
> 基本的な考え方は依存するクラスをインターフェースに置き換えて外部から与えましょうってだけ
いえ、
> Dependency Injection の基本的な考え方は、独立したオブジェクトを
> Assembler(組み立て係)として用意し、 MovieFinder インタフェースの実装を
> MovieLister クラスのフィールドへ適切に設定させるというものだ。
です Dependency Injection の基本的な考え方は、独立したオブジェクトを
> Assembler(組み立て係)として用意し、 >>231
なんか、DI嫌いな人が、DI使ってる人を「マーチンファウラーを盲信する教条主義者」として貶めようとしてるようにしか見えない。 もともとな、外部から依存関係を与えるなんてことをしなければ、
obj = new MyObject();
これだけで使えたんだよ。
MyObjectがどんなクラスに依存していたって、
それは内部実装の話で使う側からすれば関係ないからな
これをコンストラクタなどで渡すとしたら
a = new A
b = new B
c = new C(b);
obj = new MyObject(a, b);
みたいに長くなってしまうわけよ。
本末転倒じゃん?
だからこれを今までの形に近い
obj = DIContainer.create(MyObject);
とかけるようにしましょうっていうのが、DIパターンなんだよ
独立したオブジェクト(この場合はDIContainer)を組み立て役として用意してる いやいや。依存性が切れてないバージョンを出してきて「長くなったでしょ?」って…… DIContainerの生成メソッドを自分で呼び出すことはないよ > DIContainerの生成メソッドを自分で呼び出すことはないよ
そりゃフレームワークが呼び出してるからな
そのフレームワークが呼び出せるようにするためには
絶対に依存関係の定義が必要になるわけよ。
長ったらしいApplicationContext.xmlのようなやつな 直接インスタンス化すると開発する時に何かと不便じゃん
インフラが正常稼動してないと開発できない
ちょっとした動作確認にも時間がかかる
ビルド時間が長すぎる >>240
反論しろよw
>>241
クラス自体に依存関係をアノテーションで埋め込むんですよね?w
依存関係をクラス自体に書くわけですねーw >>244
それ以外ないよ?
あるって言うなら言ってくれてもいいけど、
でもないからな〜な。何を言うつもりだろー? >>242
開発中なんだからソースコード修正して開発すれば良いんだよ 今の王道DIComtainerは単純な登録タイプ
このインターフェースはこのタイプを生成しろ
あのインターフェースはこのファクトリーデリゲート使って生成しろ
みたいなやつね
KISSの原則に従って無意味な設定ファイルや制御しにくくわかりにくいアノテーションは駆逐された
シンプルなコードで普通にコンテナをビルドして実行するだけ >>251
> シンプルなコードで普通にコンテナをビルドして実行するだけ
ふーん?そのコンテナの名前は?
何で隠すの? >>253
サービスロケーターじゃないよ
マーチン・ファウラーのDIの説明ででてくるPicoContainerでもそうなってるでしょ?
https://kakutani.com/trans/fowler/injection.html#ConstructorInjectionWithPicocontainer
> MutablePicoContainer pico = configureContainer();
> MovieLister lister = (MovieLister) pico.getComponentInstance(MovieLister.class);
最近の人は、フレームワークに隠されて、詳細を知らない
DIコンテナを使ったら何故か魔法のように何もしなくても勝手に設定されると思っちゃう
でも内部的になこのようなメソッドが呼び出されてる >>255
>>236ではこれを
>obj = new MyObject();
こう書くって言ってんだろ
>obj = DIContainer.create(MyObject);
こんなの完全に Service Locator だろ。 DIContainerへの参照を持ってしまってるからな
ほらファウラーの引用
> したがって、今回のアプリケーション用 ServiceLocator は、必要に応じて MovieFinder を返すメソッドを持つことになる。そうなると当然、MovieLister から ServiceLocator への参照が発生してしまい、結果として図3のような依存関係を示すことになる。 >>257
その理屈で、
> MutablePicoContainer pico = configureContainer();
> MovieLister lister = (MovieLister) pico.getComponentInstance(MovieLister.class);
これがService Locatorにならないことの説明はできるの?
picoの参照を持ってしまっているよね?
答えを言うと、各クラスの内部で参照を持ってしまうことがService Locator うん>>236は外部から依存関係を与えずに
各クラスの内部で参照を持つと言っているからService Locator > 各クラスの内部で参照を持つと言っているからService Locator
言ってないよね?
サンプルコードもMyObjectの外部でしか使ってないよね? こう書かないと理解できないのかな?
a = new A
b = new B
c = new C(b);
obj = new MyObject(a, c);
みたいに長くなってしまうわけよ。
本末転倒じゃん?
だからこれを今までの形に近い
a = DIContainer.create(A);
b = DIContainer.create(B);
c = DIContainer.create(C, b);
obj = DIContainer.create(MyObject, a, c); >>261は依存関係の定義がない場合
依存関係の定義情報があれば
MyObjectからそれに依存する情報はわかるので
内部で以下相当のことをやることが可能になる
a = DIContainer.create(A);
b = DIContainer.create(B);
c = DIContainer.create(C, b);
だから、これだけでインスタンスを生成できる
obj = DIContainer.create(MyObject);
(MyObjectがaとcが必要であることも依存関係の定義からわかる)
obj = new MyObject(); を
obj = DIContainer.create(MyObject); こう書けるようにするためには
依存関係の定義が重要だってことがわかるだろう これぐらいDIコンテナを自分で作ったことがあれば
わかると思うんだけどな。 > 内部で以下相当のことをやることが可能になる
内部っていうのは、DIContainer.create関数内部って話ね。
MyObjectやA、B、Cクラスのことではないぞ お前らコテハンつけろ、誰が誰に何言ってるのかわからん。
とくに皮肉っぽいこと言うやつと、
皮肉言われてるやつは、コテハン必須な。 アンチは分かりやすくドカタってコテハンつけると良いぞ >>262
>obj = new MyObject(); を
>obj = DIContainer.create(MyObject); こう書けるようにするためには
だからそれService Locator
依存を注入される側でDIContainerの参照持ってるから DIContainerとServiceLocatorの区別もついてないやつがDI DIって騒いでたってこと? >>267
> 依存を注入される側でDIContainerの参照持ってるから
依存を注入される側ってどれのこと?
具体的にクラス名言って >>268
だろうね。
依存性を注入される側のコードなんて書いて無いのに
注入される側にDIContainerの参照があるとか
幻が見えてるようだしw >>268
> DIContainerとServiceLocatorの区別もついてないやつがDI DIって騒いでたってこと?
まさにそれがスレタイの狙い
DIとService Locatorの区別ができる、つまり違いを知ってる人は
Service Locatorはこう〜だけど、DIはこう〜とDIの本質を言うことができる
コンストラクタで依存しているオブジェクトを渡すという構造は
単に依存関係を分離した構造というだけで、依存関係を注入する方法を表していない
独立したオブジェクトをAssembler(組み立て係)として用意して注入する方法こそがDIなわけだよ
依存性の注入 = Dependency Injection なんだから >>272
GoFのデザインパターンにあるのはFactory MethodとAbstract Factoryであって
ファクトリーもコンテナもないので、そう聞かれても正確な答えにはならない
ファクトリー = オブジェクトを生成するもの
コンテナ = 何かの入れ物
っていうアバウトな定義でいいのであれば、その通りだが。
更に言うなら「ファクトリー+コンテナ」には、インターフェースの実装を
生成するオブジェクトのクラスフィールドに設定させるという基本的な考えを実現する機能が
抜けてるので「ファクトリー+コンテナ+依存関係の解決」がDIコンテナと言える。
これに実際のDIコンテナはAOPの機能がついてたりするんだがこっちはおまけだな >>271
Service Locatorにも組み立て係いるんだけど? ■ このスレッドは過去ログ倉庫に格納されています