X



オブジェクト指向、DIとService Locatorの違いを教えて4
■ このスレッドは過去ログ倉庫に格納されています
0001仕様書無しさん
垢版 |
2018/07/07(土) 10:47:57.49
■ オブジェクト指向・デザインパターン(有用)
 
 わかり易い例
 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/
0178仕様書無しさん
垢版 |
2018/07/08(日) 21:43:15.80
>>177
じゃあ>>140への回答はコンストラクタで設定すれば良い、でFAだな

コンストラクタで渡せばDIコンテナなんて不要なことすら分からないなんてお前はホントにアホだなw
0179仕様書無しさん
垢版 |
2018/07/08(日) 21:47:59.56
DIの使われ方を見ると依存関係がどうこうというより、
クラスに対する設定を記述しているだけな気がするな
0180仕様書無しさん
垢版 |
2018/07/08(日) 21:50:34.12
なんでアンチは自分が考えたオレオレDIをファウラーのDIみたいに言うの?
もっと提唱者に敬意を払うべきでは?
0181仕様書無しさん
垢版 |
2018/07/08(日) 21:51:14.33
オブジェクト指向にしろDIにしろ
実際に困ったことありました→ある手法を使ったことでこんなに便利になりました
ってことが明確にわかる実例がないから悪いんだよね
xmlのこのクソなげえ設定ファイルが必要ですがそれを補って有り余る程DIには利点があり
こんなに便利になりましたってのが1ミリもわからない
そこら編を死ぬほど詳しく書いた本とか売れそうな気もするんだけど誰も書かないな
0182仕様書無しさん
垢版 |
2018/07/08(日) 21:51:21.18
>>178
> じゃあ>>140への回答はコンストラクタで設定すれば良い、でFAだな

コンストラクタで設定するのはnew相当を行うときだ。
質問はnew相当のことをどうやって行うかだ

俺なら、インスタンスの作成をするにはどうすればいい?の答えに
new演算子を使用すると答えるが、
お前は、コンストラクタで設定すればいいって答えるのか?
回答が意味不明だぞ
0184仕様書無しさん
垢版 |
2018/07/08(日) 21:53:01.50
>>181
実際は新しい言葉作ってバカなPGを手玉に取ってお金を集めちゃう商売だからそんな資料は作れないよ
0186仕様書無しさん
垢版 |
2018/07/08(日) 21:54:32.74
>>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は解決する問題がなくて、
依存関係を分離しておけば、将来なにかの役に立つでしょ?になってる
0187仕様書無しさん
垢版 |
2018/07/08(日) 22:02:25.42
>>182
もともとは>>138

> MovieLister から ServiceLocator への参照が発生するのがサービスアロケータだろ

に対して、>>140が参照持たないためにはnewするしかないって言ってる

で、その回答として

コンストラクタで渡せばMovieLister から ServiceLocator への参照が発生しません

って言ってるわけ。何が意味不明なの?
0191仕様書無しさん
垢版 |
2018/07/08(日) 22:19:21.85
>>187
> コンストラクタで渡せばMovieLister から ServiceLocator への参照が発生しません

だからその場合、どうやってインスタンスを作成するのかって話をしてるんだが?
お前はインスタンス作成後の話しかしてねーじゃねーか
わざとか?


ちゃんと話を読め↓

> ないけど、事実上そうだよ。
> でないとサービスロケーターになってしまう
>
> DIパターンにおけるインスタンスを生成するオブジェクト(通常DIコンテナ)に
> 依存せずにインスタンスを生成するには、上の層でインスタンスを生成してもらわないといけない
> 上の層っていうのはフレームワークに隠蔽されたアクションに相当する処理の開始部分
>
> 「DIパターンにおけるインスタンスを生成するオブジェクト」を上の層以外の
> 部分で使うことは、それに依存してしまうことになってしまい、
> それは事実上サービスロケーターと同じことになる
0192仕様書無しさん
垢版 |
2018/07/08(日) 22:22:31.15
>>191
サービスアロケータになってしまうと言うのは貴方の感想であって
ファウラーの定義では参照がなかったらサービスアロケータではありません
0193仕様書無しさん
垢版 |
2018/07/08(日) 22:23:25.10
>>189
いいのか、その話をして?

依存関係を一箇所に書くんじゃなくて、
今は各クラスにアノテーションとして書きましょう
に変わったって言いたいんだろう?
0194仕様書無しさん
垢版 |
2018/07/08(日) 22:24:51.24
>>192
残念ながら事実だよ。
手動でnewしてしまうと、依存関係の定義情報が使用できない
0195仕様書無しさん
垢版 |
2018/07/08(日) 22:27:02.53
>>194
なんでファウラーの定義を離れて勝手なオレオレDIの話をするの?
0198仕様書無しさん
垢版 |
2018/07/08(日) 22:32:14.64
>>195-196
はい? DIの話なんかしてませんよ?
DIにならないって話をしてるんですが

この場合、DIの定義である↓を満たせない

 > Dependency Injection の基本的な考え方は、独立したオブジェクトを
 > Assembler(組み立て係)として用意し、 MovieFinder インタフェースの実装を
 > MovieLister クラスのフィールドへ適切に設定させるというものだ。

DIじゃない方を使いましょうって言ってるんでしょ?
0199仕様書無しさん
垢版 |
2018/07/08(日) 22:32:59.99
DIコンテナが無くてもDIできる。
ただしメンテナンス性が大きく下がる
0201仕様書無しさん
垢版 |
2018/07/08(日) 22:35:07.84
そりゃオレオレDIコンテナを作ればできるだろうけど、
こいつ何を言ってるんだろう?
0202仕様書無しさん
垢版 |
2018/07/08(日) 22:37:03.26
ファウラーのDIをドカタが勝手に独自解釈してるから正しただけだが?
提唱者には敬意を払わないとね
0203仕様書無しさん
垢版 |
2018/07/08(日) 22:38:07.70
>>201
オレオレDIコンテナって何それ?
ファウラーの定義に出てきますか?
0206仕様書無しさん
垢版 |
2018/07/09(月) 08:52:36.11
そうだ!Factoryが生成するインスタンスのClassを、設定ファイルに記述するようにしたらいいんじゃないかな?
0207仕様書無しさん
垢版 |
2018/07/09(月) 09:18:47.02
そもそもクラス構成なんかそうそう変えないだろ?
0208仕様書無しさん
垢版 |
2018/07/09(月) 10:50:12.45
DIコンテナもxml設定ファイルもウンコ言語Javaが産んだドカタ文化だろ
Javaのゴミさを理由にDIを貶めてんじゃねーよ
0209仕様書無しさん
垢版 |
2018/07/10(火) 06:59:02.50
services.AddTransient<IUnko>(c =>
new LogDecorator(
new TransactionScopeDecorator(
new IOValidationDecorator(
new UnkoImpl(c => c.GetService<IDepend1>(),
c.GetService<IDepend2>(),
...
))));

DIコンテナを使うとこんな馬鹿みたいな定義がずらずらと並んでしまう
これはもはやXMLより酷い
こんなんならファクトリークラスとして責務分割したほうがマシ
DIコンテナはおぞましく巨大な泥団子そのもの
オブジェクト指向信者が使っていいものじゃない
0214仕様書無しさん
垢版 |
2018/07/10(火) 20:03:09.78
>>211
> Factoryで責務分割すると、どういうこーどになるの?
違う違う。Factoryで責務分割するのではない

依存関係を外部から注入するから、こういう結果になるということなんだから
依存関係を埋め込むことで、シンプルになる。

依存関係を埋め込んでるだけでSOLID原則を破るわけではないので問題はない
(SOLID原則には依存関係を埋め込んではいけないなどという原則は無い)

またFactoryを使うなって話でもない。設計上必要な場所にはFactoryを使う
単に依存関係を分離するためにDIだかFactoryだかを使わないって話
0215214
垢版 |
2018/07/10(火) 20:03:50.30
俺は>>209ではないので念の為
0216仕様書無しさん
垢版 |
2018/07/10(火) 23:16:15.34
スマンちょっと研究したらDecoratorふつうに出来たわ
DIコンテナは神。ファクトリーはゴミという結果になってしまった
0222仕様書無しさん
垢版 |
2018/07/11(水) 10:43:43.24
依存関係注入が悪い翻訳だからね

加えて
コンポーネントはパラメーターで渡そう
コンポーネント組立は設定ファイルで
いや属性でやるだろ
とか議論の軸も整理されてない
0223仕様書無しさん
垢版 |
2018/07/11(水) 12:24:16.60
ファウラーのDIが、DIの正しい定義だって
言ってるのにそれを無視するからこうなるんだよ

ファウラーは依存関係を分離するために
依存関係を注入する側の仕組みをどうするかの話をしてるのに
依存関係が注入される側の仕組みの方を見て
注入する側の仕組みは何でも構わない、変数の型をインターフェースにしておいて、
内部でnewしなければなんでもDIだって言ってるから意味不明なことになる

議論の筋の整理のレベルじゃなくて、間違った理解をしてる
0224仕様書無しさん
垢版 |
2018/07/11(水) 13:32:11.18
>>223
ファウラーは依存関係を注入する側の仕組みについてなんて定義してるの?

って聞いてみたけど、また引用じゃなくて独自解釈を垂れるんだろうな...w
0225仕様書無しさん
垢版 |
2018/07/11(水) 14:42:49.06
>>224
書いてあるやん。
「Assemblerが適切に設定させる」というように設定部分の話をしてる
クラスにインターフェースの変数を用意してコンストラクタで渡してもらうなんて話はしてない

 http://kakutani.com/trans/fowler/injection.html

 > Dependency Injection の形式
 > Dependency Injection の基本的な考え方は、独立したオブジェクトを
 > Assembler(組み立て係)として用意し、 MovieFinder インタフェースの実装を
 > MovieLister クラスのフィールドへ適切に設定させるというものだ。
 > 依存関係は図2のようになる。
0226仕様書無しさん
垢版 |
2018/07/11(水) 15:09:17.69
依存関係を解決する側はなんでもいい
ファクトリーでもいいし
DIコンテナでもいい(というかこれはモロにファクトリー)
貧者のDIでもいいし
メインで初期化でもいい
あくまでオプション
0227仕様書無しさん
垢版 |
2018/07/11(水) 15:26:33.40
Dependency Injection の基本的な考え方は
って書いてるのに、オプションとか意味不明
基本的な考え方ぐらい理解しましょうや
0228仕様書無しさん
垢版 |
2018/07/11(水) 15:39:36.80
工場(ファクトリー)に鉄製品を作る機能をもたせたものを製鉄所というのであって、
工場だったら必ず製鉄所になるわけじゃない。

依存関係を解決する機能をもたせたものがDIなのであって
FactoryだったらかならずDIコンテナになるわけじゃない
0229仕様書無しさん
垢版 |
2018/07/11(水) 16:41:44.12
もうさ、用語として組み込み系で使いづらいんだよなぁ
0230仕様書無しさん
垢版 |
2018/07/11(水) 17:26:15.92
>>227
基本的な考え方は依存するクラスをインターフェースに置き換えて外部から与えましょうってだけ
ここまでがDIの本質

でもそうすると規模が大きくなった時に外部から与える処理自体が複雑になってくるよね
って副次的な課題に対しての解決策が幾つかあって
それがファクトリーやDIコンテナや貧者のDI
DIを語る上ではこれらは必須ではない
という意味でのオプション
0231仕様書無しさん
垢版 |
2018/07/11(水) 18:02:05.87
>>230
> 基本的な考え方は依存するクラスをインターフェースに置き換えて外部から与えましょうってだけ
いえ、

 > Dependency Injection の基本的な考え方は、独立したオブジェクトを
 > Assembler(組み立て係)として用意し、 MovieFinder インタフェースの実装を
 > MovieLister クラスのフィールドへ適切に設定させるというものだ。

です
0233仕様書無しさん
垢版 |
2018/07/11(水) 18:44:24.82
Dependency Injection の基本的な考え方は、独立したオブジェクトを
 > Assembler(組み立て係)として用意し、
0235仕様書無しさん
垢版 |
2018/07/11(水) 18:56:03.57
>>231
なんか、DI嫌いな人が、DI使ってる人を「マーチンファウラーを盲信する教条主義者」として貶めようとしてるようにしか見えない。
0236仕様書無しさん
垢版 |
2018/07/11(水) 19:15:13.17
もともとな、外部から依存関係を与えるなんてことをしなければ、

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)を組み立て役として用意してる
0237仕様書無しさん
垢版 |
2018/07/11(水) 19:26:56.11
いやいや。依存性が切れてないバージョンを出してきて「長くなったでしょ?」って……
0238仕様書無しさん
垢版 |
2018/07/11(水) 19:27:06.90
DIContainerの生成メソッドを自分で呼び出すことはないよ
0239仕様書無しさん
垢版 |
2018/07/11(水) 19:29:46.80
> DIContainerの生成メソッドを自分で呼び出すことはないよ

そりゃフレームワークが呼び出してるからな

そのフレームワークが呼び出せるようにするためには
絶対に依存関係の定義が必要になるわけよ。
長ったらしいApplicationContext.xmlのようなやつな
0242仕様書無しさん
垢版 |
2018/07/11(水) 19:32:40.31
直接インスタンス化すると開発する時に何かと不便じゃん
インフラが正常稼動してないと開発できない
ちょっとした動作確認にも時間がかかる
ビルド時間が長すぎる
0243仕様書無しさん
垢版 |
2018/07/11(水) 19:33:08.29
>>240
反論しろよw

>>241
クラス自体に依存関係をアノテーションで埋め込むんですよね?w
依存関係をクラス自体に書くわけですねーw
0245仕様書無しさん
垢版 |
2018/07/11(水) 19:34:43.07
>>244
それ以外ないよ?
あるって言うなら言ってくれてもいいけど、
でもないからな〜な。何を言うつもりだろー?
0251仕様書無しさん
垢版 |
2018/07/11(水) 19:57:43.60
今の王道DIComtainerは単純な登録タイプ

このインターフェースはこのタイプを生成しろ
あのインターフェースはこのファクトリーデリゲート使って生成しろ
みたいなやつね

KISSの原則に従って無意味な設定ファイルや制御しにくくわかりにくいアノテーションは駆逐された
シンプルなコードで普通にコンテナをビルドして実行するだけ
0254仕様書無しさん
垢版 |
2018/07/12(木) 05:09:02.12
>>251
> シンプルなコードで普通にコンテナをビルドして実行するだけ
ふーん?そのコンテナの名前は?
何で隠すの?
0255仕様書無しさん
垢版 |
2018/07/12(木) 05:12:09.92
>>253
サービスロケーターじゃないよ

マーチン・ファウラーのDIの説明ででてくるPicoContainerでもそうなってるでしょ?
https://kakutani.com/trans/fowler/injection.html#ConstructorInjectionWithPicocontainer

> MutablePicoContainer pico = configureContainer();
> MovieLister lister = (MovieLister) pico.getComponentInstance(MovieLister.class);

最近の人は、フレームワークに隠されて、詳細を知らない
DIコンテナを使ったら何故か魔法のように何もしなくても勝手に設定されると思っちゃう
でも内部的になこのようなメソッドが呼び出されてる
0257仕様書無しさん
垢版 |
2018/07/12(木) 06:32:20.62
>>255

>>236ではこれを
>obj = new MyObject();

こう書くって言ってんだろ
>obj = DIContainer.create(MyObject);

こんなの完全に Service Locator だろ。 DIContainerへの参照を持ってしまってるからな

ほらファウラーの引用
> したがって、今回のアプリケーション用 ServiceLocator は、必要に応じて MovieFinder を返すメソッドを持つことになる。そうなると当然、MovieLister から ServiceLocator への参照が発生してしまい、結果として図3のような依存関係を示すことになる。
0258仕様書無しさん
垢版 |
2018/07/12(木) 08:11:31.68
>>257
その理屈で、

> MutablePicoContainer pico = configureContainer();
> MovieLister lister = (MovieLister) pico.getComponentInstance(MovieLister.class);

これがService Locatorにならないことの説明はできるの?
picoの参照を持ってしまっているよね?


答えを言うと、各クラスの内部で参照を持ってしまうことがService Locator
0259仕様書無しさん
垢版 |
2018/07/12(木) 08:45:59.54
うん>>236は外部から依存関係を与えずに
各クラスの内部で参照を持つと言っているからService Locator
0260仕様書無しさん
垢版 |
2018/07/12(木) 08:52:46.71
> 各クラスの内部で参照を持つと言っているからService Locator

言ってないよね?
サンプルコードもMyObjectの外部でしか使ってないよね?
0261仕様書無しさん
垢版 |
2018/07/12(木) 08:54:37.27
こう書かないと理解できないのかな?

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);
0262仕様書無しさん
垢版 |
2018/07/12(木) 08:58:11.42
>>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); こう書けるようにするためには
依存関係の定義が重要だってことがわかるだろう
0263仕様書無しさん
垢版 |
2018/07/12(木) 08:59:22.67
これぐらいDIコンテナを自分で作ったことがあれば
わかると思うんだけどな。
0264仕様書無しさん
垢版 |
2018/07/12(木) 09:36:10.66
> 内部で以下相当のことをやることが可能になる

内部っていうのは、DIContainer.create関数内部って話ね。
MyObjectやA、B、Cクラスのことではないぞ
0265仕様書無しさん
垢版 |
2018/07/12(木) 10:09:47.52
お前らコテハンつけろ、誰が誰に何言ってるのかわからん。
とくに皮肉っぽいこと言うやつと、
皮肉言われてるやつは、コテハン必須な。
0266仕様書無しさん
垢版 |
2018/07/12(木) 10:25:40.51
アンチは分かりやすくドカタってコテハンつけると良いぞ
0267仕様書無しさん
垢版 |
2018/07/12(木) 10:34:11.16
>>262
>obj = new MyObject(); を
>obj = DIContainer.create(MyObject); こう書けるようにするためには

だからそれService Locator
依存を注入される側でDIContainerの参照持ってるから
0268仕様書無しさん
垢版 |
2018/07/12(木) 12:16:33.28
DIContainerとServiceLocatorの区別もついてないやつがDI DIって騒いでたってこと?
0269仕様書無しさん
垢版 |
2018/07/12(木) 13:53:06.70
>>267
> 依存を注入される側でDIContainerの参照持ってるから

依存を注入される側ってどれのこと?
具体的にクラス名言って
0270仕様書無しさん
垢版 |
2018/07/12(木) 13:54:17.71
>>268
だろうね。
依存性を注入される側のコードなんて書いて無いのに
注入される側にDIContainerの参照があるとか
幻が見えてるようだしw
0271仕様書無しさん
垢版 |
2018/07/12(木) 14:22:31.54
>>268
> DIContainerとServiceLocatorの区別もついてないやつがDI DIって騒いでたってこと?
まさにそれがスレタイの狙い
DIとService Locatorの区別ができる、つまり違いを知ってる人は
Service Locatorはこう〜だけど、DIはこう〜とDIの本質を言うことができる

コンストラクタで依存しているオブジェクトを渡すという構造は
単に依存関係を分離した構造というだけで、依存関係を注入する方法を表していない

独立したオブジェクトをAssembler(組み立て係)として用意して注入する方法こそがDIなわけだよ
依存性の注入 = Dependency Injection なんだから
0272仕様書無しさん
垢版 |
2018/07/12(木) 14:36:24.22
それって、ファクトリー+コンテナ?
0273仕様書無しさん
垢版 |
2018/07/12(木) 14:47:58.38
>>272
GoFのデザインパターンにあるのはFactory MethodとAbstract Factoryであって
ファクトリーもコンテナもないので、そう聞かれても正確な答えにはならない

ファクトリー = オブジェクトを生成するもの
コンテナ = 何かの入れ物
っていうアバウトな定義でいいのであれば、その通りだが。

更に言うなら「ファクトリー+コンテナ」には、インターフェースの実装を
生成するオブジェクトのクラスフィールドに設定させるという基本的な考えを実現する機能が
抜けてるので「ファクトリー+コンテナ+依存関係の解決」がDIコンテナと言える。
これに実際のDIコンテナはAOPの機能がついてたりするんだがこっちはおまけだな
0275仕様書無しさん
垢版 |
2018/07/12(木) 20:49:03.06
その組立係を何処から参照しているかの違いですね
■ このスレッドは過去ログ倉庫に格納されています

ニューススポーツなんでも実況