【Swift】Bastard Injection の問題点、あるいは依存性逆転の原則について。または needle というDIコンテナの紹介。

私達は、物事を分割して考えることしかできない。

それ故、私達は1つのクラスにすべてを書かず、クラスを分割する。

```swift
class FeatureA {
    func foo(): String {
        let b = FeatureB() // Use `FeatureB`
        return b.bar() + "!!"
    }
}

class FeatureB {
    ...
    func bar(): String {
        // do something
    }
}
```

ここでは、`FeatureA` クラスが `FeatureB` クラスを利用している。こういう時、 `FeatureA` は `FeatureB` に依存していると表現される。`FeatureB` が存在しなければ、`FeatureA` は利用できないからだ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29653/e50c7cf7-99c4-cff6-12a7-8a0911f5e5d1.png)

前述のコードは問題なく動作するが、`FeatureA` のユニットテストをしたい時に問題が起こる。`FeatureB` をテスト用のモックに差し替えられないのだ。

だから、私達は Protocol という道具を使って、`FeatureB` を差し替えられるようにする。

例えば、以下のように。

```swift
class FeatureAImpl {
    let b: FeatureB

    init(b: FeatureB) {
        self.b = b
    }

    func foo(): String {
        return b.bar() + "!!"
    }
}

// Introduce protocol
protocol FeatureB {
    func bar(): String
}

// Implement `FeatureB`
class FeatureBImpl: FeatureB {
    ...
    func bar(): String { ... }
}
```

インターフェースと実装を分離する意味で、実装クラスの末尾には `Impl` という単語を付けるように変更した。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29653/85b8bdc2-c072-9154-1e44-0953ff9480b4.png)

UMLに詳しくない人のために補足しておくと、点線矢印が依存（dependency）、白抜きの三角矢印が実装（implementation）を表す。この記事を読み進める上では、それだけ理解しておけば概ね十分なはずだ。

ここでは `FeatureB` という依存性を外部から与えられるになっているが、これは一般的に『DI（依存性注入）』と呼ばれる。この例では、コンストラクタ経由でそれを行えるようにしているため、『コンストラクタインジェクション』などというパターン名が付けられている。

さて、これによって `FeatureAImpl` のユニットテストはもはや容易になった。

```swift
// Mock for unit-test
class FeatureBMock: FeatureB {
    func bar(): String { return "Hello" }
}

let mock = FeatureBMock()
let a = FeatureAImpl(b: mock) // Constructor Injection
XCTAssertEqual("Hello!!", a.foo())
```

ところで、プロダクションコードにおいて `FeatureBImpl` を生成するのはどこでやるべきだろう？　呼び出し元でいちいち生成するのは面倒だし、そもそも我々はテスタビリティのためだけに Protocol を導入したのだから、生成するのは常に `FeatureBImpl` のみだ。

だから私達は通常、以下のようにデフォルト引数で用意する。

```swift
class FeatureAImpl {
    let b: FeatureB

    init(b: FeatureB = FeatureBImpl()) { // Bastard Injection
        self.b = b
    }
}

// Initialize and use
let a = FeatureAImpl()
a.foo()
```

これは十分うまく機能する。

依然として `FeatureB` はユニットテスト用のモックに差し替え可能だし、`FeatureAImpl` の利用者に `FeatureBImpl` を意識させる必要もないし、ボイラープレート的なコードも存在しない。

ただし、これは DI においてアンチパターンの一種とされており、”Bastard Injection”などと呼ばれている。

この記事のタイトルに含まれているものだ。

## モジュール間の結合
しかし、Bastard Injection の何がマズイのだろうか？　インターネット上の記事では以下のように説明されることが多いように思う。

> `FeatureAImpl` は依然として `FeatureBImpl` に依存しており、これは結合度が強い状態である。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29653/3897d854-eac3-1249-1fc5-eba3846ff1c0.png)

あぁ、確かにそのとおりだ。

実際のところ `FeatureAImpl` は `FeatureBImpl` なしではコンパイルすることができない。もちろん、私達はソフトウェア開発において、結合度が弱いに越したことはないことを理解している。

しかし、具体的にどのようなデメリットが発生するのだろう？　　我々は、単に”結合度を弱くしたい”という理由だけで、Bastard Injection の手軽さを手放すようなことはしたくない。それがゼロコストであるならば話は別だが。

結論から言えば、複数のモジュールに分割した時にモジュール間に依存が発生し、それが大きな問題になることがある。他にも細かい問題が起こりうるが、おそらくこれが一番大きいだろうと思う。

例えば、`FeatureA` と `FeatureB` をそれぞれ `A` と `B` というモジュールに分割したとする。

```swift
// 📦 A

import B // Dependency to B module

class FeatureAImpl {
    let b: FeatureB

    init(b: FeatureB = FeatureBImpl()) {
        self.b = b
    }
    ...
}


// 📦 B

protocol FeatureB { ... }

class FeatureBImpl: FeatureB {
    ...
}
```

外部モジュールに公開するためには `public` 修飾子が必要となるが、本質的なコードに着目できるようにコード例からは除外している。

当然ながらモジュール間には `A` →  `B` という依存関係が発生する。言い換えると、`A` モジュールをビルドするためには、`B` モジュールが必須になる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29653/9cbfeba0-1597-b59d-ae9b-6839b893bc44.png)

結果として、ビルド時間が増加したり、モジュールごとに独立して開発する際の妨げになることがある。それはコードベースやモジュールの数が増えるに従って、より現実的な問題として現れてくる。

また、iOSアプリ開発などにおいては、機能（Feature）ごとにモジュールを分割している場合、モジュール間で相互に画面遷移が発生した場合に、循環依存が発生してビルドできないという問題にも遭遇しうる。

もちろん、これが課題になることもあれば、そうでないこともある。

少なくとも小さなプロジェクトであれば、問題が表面化するケースは少ないはずだ。しかし、昨今ではマルチモジュールによる開発も一般的になりつつあり、こうした問題を解決しておけるに越したことはない。

しかし、この問題は Bastard Injection を無くしただけでは解決できないことが分かる。`FeatureBImpl` への依存を無くしても、依然として `FeatureB` Protocol には依存しているからだ。

では、どのように解決できるのだろう？

## 依存性逆転の原則
例えば、以下のようにしたらどうだろう？

```swift
// 📦 A

class FeatureAImpl {
    let b: FeatureB

    init(b: FeatureB) { // Remove Bastard Injection
        self.b = b
    }
    ...
}

protocol FeatureB { ... } // Moved from B module


// 📦 B

import A // Dependency

class FeatureBImpl: FeatureB { // new Dependency
    ...
}
```

このコード例では、Bastard Injection していた箇所をなくし、 `FeatureB` Protocol を `A` モジュールに移動している。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29653/94f7f80a-370f-5c47-b496-c759d5531132.png)

この変更によって、モジュール間の依存関係は `A` → `B` という向きから、`B` → `A` という逆の依存関係を持つようになった。

これは『依存性逆転の原則』とも呼ばれており、それを説明する際の一般的なコード例にあたる。

> 1. 上位モジュールはいかなるものも下位モジュールから持ち込んではならない。双方とも抽象（例としてインターフェース）に依存するべきである。
> 
> 2. 抽象は詳細に依存してはならない。詳細（具象的な実装内容）が抽象に依存するべきである。

[引用：Wikipedia（依存性逆転の原則）](https://ja.wikipedia.org/wiki/%E4%BE%9D%E5%AD%98%E6%80%A7%E9%80%86%E8%BB%A2%E3%81%AE%E5%8E%9F%E5%89%87)

しかし、モジュール間の依存関係 `B` → `A` は依然として残っており、モジュール単位で独立してビルド・開発することは実現できていない。これを解決するにはどうしたらよいだろうか？

## インターフェース用のモジュール
1つの方法として、インターフェース用のモジュールを別途用意するやり方が考えられる。

```swift
// 📦 Interface

protocol FeatureA { ... } // new!
protocol FeatureB { ... } // Moved from A module


// 📦 A

import Interface

class FeatureAImpl: FeatureA {
    let b: FeatureB

    init(b: FeatureB) {
        self.b = b
    }
    ...
}


// 📦 B

import Interface

class FeatureBImpl: FeatureB {
    ...
}
```

ここでは `Interface` というモジュールを新たに用意し、そこに Protocol を移動している。ついでに `FeatureA` についても Protocol を導入している。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29653/28f2efd0-3471-59e4-f37c-050c623e527f.png)

これによって `A` と `B` のモジュール間の依存性はなくなり、どちらも `Interface` というインターフェースだけを含むモジュールにのみ依存するようになった。

* `A` → `Interface`
* `B` → `Interface`

『依存性逆転の原則』の言葉に合わせるなら、”モジュールは双方ともインターフェースという抽象モジュールにのみ依存する”ようになった。

## Bastard Injection を無くした代償
さて、これですべての問題が解決したかというとそんなことはない。

Bastard Injection を無くした為、今度は呼び出し元で依存するオブジェクトを生成しなくてはならなくなる。

```swift
// 📦 Main

import Interface
import FeatureA
import FeatureB

// Dependency objects
let b = FeatureBImpl()

let a = FeatureAImpl(b: b) // DI
a.foo()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29653/6004db45-01ca-0b3b-8c50-611c9b9d2dcc.png)

この例では、大したことが無いように見えるが、仮に `FeatureAImpl` がより多くの依存オブジェクトを必要としていた場合はどうだろう？　あるいは、`FeatureBImpl` が依存オブジェクトを必要としていた場合は？　さらにその依存オブジェクトが別の依存オブジェクトを必要としていたら？

```swift
// 📦 Main

...

// dependency objects
let e = FeatureEImpl()
let d = FeatureDImpl(e: e) // DI
let c = FeatureCImpl()
let b = FeatureBImpl(d: d) // DI

let a = FeatureAImpl(b: b, c: c) // DI
a.foo()
```

実のところ依存関係は複雑になるのが一般的であり、Bastard Injection を手放した結果として、呼び出し元におけるボイラープレートのコードが大量に増えることになる。

私たちはオブジェクトを組み立てるコードを書きたいわけではない、単にそれを利用したいだけだ。

**いっそのこと、こうしたオブジェクトの依存関係を勝手に解決してくれたらいいのに！**

過去の賢明な開発者たちも同じように考えた。その結果として『DIコンテナ』というものが生み出された。

## DIコンテナ
DIコンテナの考え方はシンプルで、依存関係を事前に定義しておき、オブジェクトを生成する際の依存関係はDIコンテナ側で勝手に解決してしまおうというものだ。

以下は擬似コードだが、DI コンテナの動作イメージを理解するのには役立つはずだ。

```swift
let container = DIContainer()

// Register objects
container.register(FeatureAImpl.class)
container.register(FeatureBImpl.class)

// Get object
let a = container.get(for: FeatureA.class)
a.foo()
```

事前に `FeatureAImpl` と `FeatureBImpl` を登録しておくことで、`FeatureAImpl` → `FeatureBImpl` という依存関係が勝手に解決された `FeatureAImpl` が手に入る。

これは依存関係がどれだけ深くネストしていようと変わらない。言い換えると、`FeatureA` が欲しいとだけ言えば、依存関係が解決されたオブジェクトが手に入り、我々はそれをただ使うだけだ。

Bastard Injection を利用した時とコード量は殆ど変わらないことが分かるはずだ。

## uber/needle
Swift においても DI コンテナはいくつか開発されているが、ここでは Uber がメンテしている needle を紹介しようと思う。

https://github.com/uber/needle

なぜ needle なのかと言えば、私が触ったことがあるのが needle だけという単純な理由からなのだが、needle はコンパイルタイムセーフで、ボイラープレートに相当するコードを自動生成する仕組みを備えており、開発者にとって扱いやすい DI コンテナであろうと思う。

日本においても実プロダクトに導入しているケースもあるようだ。

[needleでDI改善に取り組み始めた話](https://note.com/reality_eng/n/nbe40c0e17690)
[needleでモジュール間の画面遷移を実現した話 REALITY Advent Calendar #17](https://note.com/reality_eng/n/n124fd7da93c3)

なお、この記事は needle の入門記事ではないし、もちろん needle の API リファレンスでもない。なんとなく needle の大まかな雰囲気を理解してもらおうという趣旨なので、実際に利用する際はリポジトリの README などを参照して欲しい。

さて、DIコンテナを利用する際は、依存関係の定義とオブジェクトの登録が必要になる。needle では、例えば以下のように書くことができる。

```swift
import NeedleFoundation

class RootComponent: BootstrapComponent {

    // register object
    var b: FeatureB {
        FeatureBImpl()
    }
    
    // child component
    var aComponent: AComponent {
        AComponent(parent: self)
    }
}

protocol ADependency: Dependency {
    var b: FeatureB { get } // depended to FeatureB
}

class AComponent: Component<ADependency> {

    // register object
   var a: FeatureA {
        FeatureAImpl(b: dependency.b) // resolve dependency
    }
}
```

これは初見では複雑に見えるかもしれない。

順に見ていこう。まず、needle を構成する要素の1つである `Component` からだ。

`Component` という名称がややこしいが、これは一種の名前空間・スコープを表現するものだ。そして、needle は階層的な依存関係定義を推奨しており、`Component` は階層的に定義できる。

このコード例では、以下のような名前空間・スコープが生まれていることが分かる。

```swift
class RootComponent: BootstrapComponent {
    ...

    // child component
    var aComponent: AComponent {
        AComponent(parent: self)
    }
}

class AComponent: Component<ADependency> {
    ...
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29653/e4bf4a9f-3a24-3307-7552-b385b1885951.png)

この階層的な名前空間に、オブジェクトを配置していくイメージとなる。

次に、needle を構成するもう1つの要素である `Dependency` だ。これはその名のとおり依存を表現するもので、今回のコードでは `FeatureB` への依存を定義している。

```swift
protocol ADependency: Dependency {
    var b: FeatureB { get } // Dependency to FeatureB
}
```

そして、この依存を利用しているのが以下のコードだ。

```swift
class AComponent: Component<ADependency> {
    var a: FeatureA {
        FeatureAImpl(b: dependency.b) // resolve dependency
    }
}
```

すなわち、`AComponent` は `ADependency` という依存を持っており、より具体的に言うならば `FeatureB` に依存している。

この `AComponent` には `FeatureA` 型の `a` プロパティが定義されているが、これが DI コンテナへのオブジェクトの登録に相当するコードになる。`dependency` というプロパティは `Component` に用意されており、ジェネリクスで指定した `Dependency` のプロパティにアクセスできる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29653/444855b0-c73a-7f9a-af79-e7107150d2ea.png)

こうして、`FeatureAImpl` の依存関係を解決して生成することを実現している。

ところで、この `dependency.b` で手に入る実体、すなわち `FeatureBImpl` はどこで生成されるのだろう？　その定義を行っているのが、`RootComponent` における以下のコードとなる。

```swift
class RootComponent: BootstrapComponent {

    // register object
    var b: FeatureB {
        FeatureBImpl()
    }
    ...
}
```

まとめると、以下のようにオブジェクトが配置されているイメージとなる。

* RootComponent
	* `b: FeatureB = FeatureBImpl()`
	* AComponent
		* `a: FeatureAImpl(b: dependency.b)`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29653/587b1d6f-29c6-3454-9459-01ce7f69d95f.png)

`FeatureAImpl` を生成する際に、`dependency.b` とすることで、親の Component である `RootComponent` から `b` を取り出していることになる。これは階層がどれだけネストしていようと関係なく、needle は祖先のどこかに依存オブジェクトが定義されていれば、自動的に引っ張ってくる。

それはいささか魔法のように聞こえるかもしれないが、needle ではそれに相当するコードを自動生成するコマンドラインツールを提供している。

```bash
$ needle generate Sources/needle.generated.swift Sources
```

このコマンドは `Sources` ディレクトリ内のすべてのソースを解析し、実行する際に必要な `Sources/needle.generated.swift` を生成する。あとはビルド対象にこのソースを含めれば準備は完了となる。

さて、最後にコンテナからオブジェクトを取得するコードを見てみよう。

起動時に`registerProviderFactories` という関数を一度だけ呼ぶ必要があることにだけ注意しよう。

```swift
import NeedleFoundation

registerProviderFactories() // Required

let component = RootComponent() // Create `RootComponent`

let a = component.aComponent.a // Get object
a.foo()

let b = component.b // In the same way
b.bar()
```

これで無事に Bastard Injection を利用すること無く、目的となるものが手に入った。

needle は複雑に感じただろうか。

しかし、結局のところ以下の繰り返しであり、依存関係の定義とオブジェクトの配置を行っているに過ぎず、慣れれば一種の DSL として受け入れられるはずだ。

* `Component` で（階層的な）名前空間を作る
* `Dependency` で Component が依存するものを定義する
* 実体となるオブジェクトを生成するプロパティを `Component` 階層の祖先のどこかに設置する

また、この記事では説明しなかったが、インスタンスを Singleton として扱えるようにする `shared` という便利なメソッドも用意されている。インスタンス生成の責務を DI コンテナに一任できるのは一つのメリットと言える。

ところで、我々はモジュールを分割しているのだった。needle のコードを含め、各コードがどのモジュールに配置されているのか全体のコード例を示す（依然として `public` は省略している）。

```swift
// 📦 Interface

protocol FeatureA {
    func foo(): String
}

protocol FeatureB {
    func bar(): String
}


// 📦 Main

import Interface
import A
import B
import NeedleFoundation

class RootComponent: BootstrapComponent {

    var b: FeatureB {
        FeatureBImpl()
    }

    var aComponent: AComponent {
        AComponent(parent: self)
    }
}

registerProviderFactories()

let a = RootComponent().aComponent.a
a.foo()


// 📦 A

import Interface
import NeedleFoundation

protocol ADependency: Dependency {
    var b: FeatureB { get }
}

class AComponent: Component<ADependency> {
   var a: FeatureA {
        FeatureAImpl(b: dependency.b)
   }
}

class FeatureAImpl {
    let b: FeatureB

    init(b: FeatureB) {
        self.b = b
    }

    func foo(): String {
        return bar() + "!!"
    }
}


// 📦 B

import Interface

class FeatureBImpl: FeatureB {
    init() {}

    func bar(): String {
        // do something
    }
}
```

モジュール間の依存は必要最低限になっており、ボイラープレートのようなコードも殆ど存在しないことが分かる。

## Bastard Injection を利用し続けるメリット
さて、この記事では Bastard Injection の問題点と、それをやめた場合にコストとなるオブジェクトの依存解決を DI コンテナによって解決できるという内容を書いてきたが、それでも Bastard Injection を利用し続けるメリットはあるだろうか？

第1に、Bastard Injection は殆どのケースで十分に機能する。テスタビリティは確保できるし、それをやるためのコストも殆どない。実際に Apple は過去の WWDC において、Bastard Injection を利用したテスト方法を紹介している。

第2に、Bastard Injection は驚くほどシンプルだ。コンストラクタのデフォルト引数をサポートしていない言語では面倒だが、それをサポートしている Swift においては最低限のコード量で済む。needle は最低限のコード量で済むようになっており、依存関係を明確化できるというメリットもあるが、それでも管理するコード量は増える。

第3に、コードの追跡がしやすい。実装クラスがコンストラクタのデフォルト引数に書かれているので、Xcode から実装クラスをたどることは容易だ。Bastard Injection を利用しない場合においても、命名規約（`Impl` など）によってカバーできるだろうが、コードジャンプはしづらくなるはずだ。

つまるところ、あなたが Bastard Injection による現実的な課題に遭遇していない場合、それを廃止して DI コンテナを利用するように切り替えるべき**強い理由**はない。

しかし、プロジェクトの後半になってからテストや CI を導入するのに大きな傷みを伴うのと同様、あとから DI コンテナを導入するのにもそれなりの痛みが伴うはずだ。

あなたが新規プロジェクト、あるいは今後発展しうる可能性のある小さなプロジェクトで作業している場合、早めに導入することで、そのコストを最小限にできる可能性はある。

## 詳細ではなく抽象に依存する
ここまで長々と見てきたが、結局のところ私達は何を手に入れたのだろうか。

最初のコードの問題点は、`FeatureAImpl` が `FeatureBImpl` という詳細（実装）を知っていたことにある（名前は `Impl` 付きに変更している）。

```swift
class FeatureAImpl {
    func foo(): String {
        let b = FeatureBImpl() // Depends on details
        return b.bar() + "!!"
    }
}

class FeatureBImpl {
    func bar(): String { ... }
}
```

それを `FeatureB` という抽象に依存するようにし、詳細（実装）である `FeatureBImpl` を知らなくすることで、`FeatureB` を任意の詳細（実装）に差し替え可能にし、`FeatureAImpl` 単体でコンパイルすることを可能にした。

```swift
class FeatureAImpl {
    let b: FeatureB

    init(b: FeatureB) { // Depends on abstraction
        self.b = b
    }

    func foo(): String {
        return bar() + "!!"
    }
}

protocol FeatureB {
    func bar(): String
}

class FeatureBImpl: FeatureB {
    init() {}

    func bar(): String { ... }
}
```

マルチモジュールにおいては、`Interface` という抽象モジュールを用意することで、モジュール間の依存を無くすことで、モジュール単体でのビルドを可能にし、任意のモジュールに差し替えることも可能にした。

```swift
// 📦 Interface

protocol FeatureA { ... }
protocol FeatureB { ... }


// 📦 A

import Interface // Depends on abstraction

class FeatureAImpl: FeatureA {
    let b: FeatureB

    init(b: FeatureB) { // Depends on abstraction
        self.b = b
    }
    ...
}


// 📦 B

import Interface // Depends on abstraction

class FeatureBImpl: FeatureB {
    func bar(): String { ... }
}
```

結局のところ、詳細ではなく**抽象**に依存するように変更したに過ぎない。

> 1. 上位モジュールはいかなるものも下位モジュールから持ち込んではならない。双方とも抽象（例としてインターフェース）に依存するべきである。
> 
> 2. 抽象は詳細に依存してはならない。詳細（具象的な実装内容）が抽象に依存するべきである。

シングルモジュールにおいては `FeatureBImpl` という詳細を剥がすために `FeatureB` という抽象を導入し、マルチモジュールにおいては `B` モジュールという詳細を剥がすために、`Interface` という抽象を導入した。

**詳細を知らないようにする**ことで、私達はそれを差し替え可能にし、独立してビルドすることを可能にする。それをクラス間で行うか、モジュール間で行うか、それだけの違いなのである。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29653/f9c7cf94-8ce0-7802-2652-4d3fdfe60f7e.png)

DIコンテナは、単にこれを補完するための仕組みの1つに過ぎない。

## まとめ
* Bastard Injection は殆どのケースで十分に機能する。
* ただし、マルチモジュールの場合にモジュール間の依存が発生する。
* モジュール間の依存は、ビルド時間の増大などの様々な問題を引き起こす。
* Bastard Injection を廃止し、依存性逆転の原則を適用することでそれを解消できる。
* オブジェクトを組み立てる処理が大変になるが、DI コンテナによって負担を軽減できる。
* uber/needle は Swift 向けの DIコンテナの1つで、コンパイルタイムセーフである。
* テストや CI と同様、プロジェクトの早期に導入することで、将来的な導入コストを減らせる。
* 詳細を知らないようにすれば、差し替え可能になり、独立してビルドできる。

## Q&A - 追記：2022/03/02

### Q. `FeatureA`と`FeatureB`を同一の`Interface`モジュールに配置したのはなぜ？

もちろん分けても構わない。

例えば、今回のケースにおいては`InterfaceA`と`InterfaceB`という2つのモジュールに分けても全く問題ない。

しかし、`InterfaceA`と`InterfaceB`に何らかの依存があった場合、インターフェース用のモジュール同士で依存が発生する。

より極端なケースにおいては以下のようなケースも考えられる。

```swift
// 📦 InterfaceA
protocol A {
    func createB() -> B
}

// 📦 InterfaceB
protocol B {
    func createA() -> A
}
```

これは`InterfaceA`と`InterfaceB`でモジュール間の循環参照が発生しており、これはSwiftコンパイラによって弾かれる。

```
cyclic dependency declaration found: A -> B -> InterfaceB -> InterfaceA -> InterfaceB
```

一方で、循環参照が発生しないように設計するのであれば、`import InterfaceXxx`という宣言によって、依存しているインターフェース用のモジュールがソースコード上で明確化されるというメリットも考えられる。

私もインターフェース用のモジュールを分割した経験はないので、このあたりのノウハウをお持ちの方はコメントなりで教えて欲しい。

## あとがき
久しぶりの技術記事のためか、翻訳記事のような文体になってしまいましたが、誰かしらの参考になれば幸いです。

なお、私自身 uber/needle を深く触ったわけではない為、この記事では十分に言及できていない可能性があります。例えば、現状で見えている大きな欠点として、`associatedtype`を持つプロトコルを DI の対象にできない、といった問題を見つけています。

より実践的に触った際は、あらためて記事に起こしたいと思います。