バニラDIについて

# はじめに

こちらの記事は議論がすすみ@Kuniwak さんに改めてまとめていただきました。

- https://qiita.com/Kuniwak/items/59106fbb02623393b494

過去の記事はコメントアウトしておきます。

<!--


# はじめに

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">もしもし夏休み子どもDI電話相談ですか、この記事で著者らが「バニラDI」と言っているのはコンストラクタインジェクションと何が違うのでしょうか。またこれの課題である“依存の依存が書きにくい”という問題を「設計破綻」と言っていますがどうなんでしょうか。<a href="https://t.co/fJQXnjc3IN">https://t.co/fJQXnjc3IN</a></p>&mdash; 吉村 優 / Yuu YOSHIMURA (@_yyu_) <a href="https://twitter.com/_yyu_/status/1037954329578106880?ref_src=twsrc%5Etfw">2018年9月7日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

この議論に対して、著者らから次のような投稿があった。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">初めまして。その記事の著者です。おっしゃる通り、バニラDIは **ほぼ** コンストラクタ注入の言い換えです（記事中でも言及があります）。あえて別の名前をつけたのは、DIに特別なライブラリ（=DIコンテナ）が必ずしも必要ではないことを強調するためです。（続く <a href="https://t.co/krFIRi5QrZ">https://t.co/krFIRi5QrZ</a></p>&mdash; Kuniwak@A man using Vanilla DI/Mock (@orga_chem) <a href="https://twitter.com/orga_chem/status/1037991810868555776?ref_src=twsrc%5Etfw">2018年9月7日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr">続き）この「コンストラクタ注入」という言葉は、セッタ注入との対比で使われる言葉だと理解していますが、それより私は「DI コンテナ」と対比する言葉がほしいと思っていました。というのも、DI したいからと DI コンテナに盲目に飛びつく人があまりにも多かったからです。（続く</p>&mdash; Kuniwak@A man using Vanilla DI/Mock (@orga_chem) <a href="https://twitter.com/orga_chem/status/1037992416769335302?ref_src=twsrc%5Etfw">2018年9月7日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr">続き）そこで、私は「DIコンテナ」に対比する言葉として「バニラDI」を導入しました。また、バニラ DI が基本的にコンストラクタ注入な理由は、セッタ注入より欠点が少ないからです。つまり、セッタ注入も欠点があるもののバニラDIの一形態と捉えられます（この点が **ほぼ** と強調した部分です（続く</p>&mdash; Kuniwak@A man using Vanilla DI/Mock (@orga_chem) <a href="https://twitter.com/orga_chem/status/1037992520674725888?ref_src=twsrc%5Etfw">2018年9月7日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr">続き）さて、もう一つのご質問である「依存の依存が書きにくい問題」についてもお話しします。これは一言でいうと「デメテルの法則違反」です。デメテルの法則は「オブジェクトは自身の間接的な依存を知っていてはいけない」というものです。（続く</p>&mdash; Kuniwak@A man using Vanilla DI/Mock (@orga_chem) <a href="https://twitter.com/orga_chem/status/1037992626119532544?ref_src=twsrc%5Etfw">2018年9月7日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr">続き）なぜ、間接的な依存を知っていてはいけないかという理由を、A -&gt; B -&gt; C の依存関係を例に説明します。ここで A と C は間接的な依存関係にありますが、もし A が C を知ってしまうと、デメテルの法則に違反することになります。（続く</p>&mdash; Kuniwak@A man using Vanilla DI/Mock (@orga_chem) <a href="https://twitter.com/orga_chem/status/1037992702040666112?ref_src=twsrc%5Etfw">2018年9月7日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr">続き）ここで注目してほしいのは、A が C を知ってしまうと、B から C への依存を切り離したとき意図せず A が壊れるといった問題が起こることです。これは B をメンテする人にとっては頭の痛い問題です。これが設計が破綻していると表現した理由になります。</p>&mdash; Kuniwak@A man using Vanilla DI/Mock (@orga_chem) <a href="https://twitter.com/orga_chem/status/1037992838611394560?ref_src=twsrc%5Etfw">2018年9月7日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr">全てを読ませていただきました。まず、コンストラクタインジェクションにあえて別名を付けたことは理解しました。</p>&mdash; 吉村 優 / Yuu YOSHIMURA (@_yyu_) <a href="https://twitter.com/_yyu_/status/1038037018389798913?ref_src=twsrc%5Etfw">2018年9月7日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

これ以上はTwitterで議論しづらいので、Qiitaに移行する。

# 「依存の依存」に対する自分の意見

- @orga_chemさんが仰っている「オブジェクトは自身の間接的な依存を知っていてはいけない」という議論は、元記事にある“悪い例”においても達成されているように見える

```swift
class SomethingGreatService {
    private let foo: Foo
    private let bar: Bar
    private let fooBar: FooBar
    private let baz: Baz
    private let qux: Qux
    private let quux: Quux

    // ....
}
```

- これは`SomethingGreatService`が依存している`Foo`や`Bar`が何に依存しているのか、については隠蔽されているように見える
- たとえばこれが次のようにインスタンシエイトされたとしても、`SomethingGreatService`のメンバ変数である`foo`の依存（つまり依存の依存）である`corge`は適切に`private`とされているはずで、アクセスはできないはず

```swift
let service = SomethingGreatService(
    foo: Foo(),
    bar: Bar(
        corge: Corge()
    ),
    fooBar: FooBar(
        grault: Grault(
            garply: Garply()
        )
    ),
    baz: Baz(
        waldo: Waldo()
    ),
    qux: Qux(),
    quux: Quux(
        plugh: Plugh()
    )
)
```
- DDDの文脈では、Presenter → UseCase → DomainService → Repository → Infraといった層構造となるので、依存の依存が発生することが悪い設計となるならば、:point_up_2:このような構造はどうすればよいのだろうか？

-->