Dependency Injection in MVVM Architecture with ReactiveCocoa Part 1: 導入

以下のブログ記事の翻訳です[^訳注1]。

[Dependency Injection in MVVM Architecture with ReactiveCocoa Part 1: Introduction](https://yoichitgy.github.io/post/dependency-injection-in-mvvm-architecture-with-reactivecocoa-part-1-introduction/)

* * *

[前回のブログ記事](http://qiita.com/yoichitgy/items/91ab2b4fa604391619bd)では、シンプルなアーキテクチャのアプリを開発する中で、[Swinject](https://github.com/Swinject/Swinject)を用いたdependency injectionについて説明しました。今回からのシリーズでは、[ReactiveCocoa](https://github.com/ReactiveCocoa/ReactiveCocoa)を用いて[MVVM (Model-View-ViewModel)](https://en.wikipedia.org/wiki/Model_View_ViewModel)アーキテクチャのアプリを開発し、その中でdependency injectionを行います。

シリーズを通して以下のことを学びます。

1. MVVMアーキテクチャを明示的に表現するXcodeプロジェクトの設定方法
2. Swinjectを用いてMVVMアーキテクチャの中でdependency injectionを行う方法
3. ReactiveCocoaを用いてModelからViewModel、ViewModelからViewへとイベントを伝播させる方法

シリーズではdependency injection、Swinject、MVVM、ReactiveCocoaを利用した実践的な開発に焦点を当てます。それぞれの詳細については別の記事を参考にしてください。推奨する記事については後で記事の中で紹介します。

これから開発する例題のアプリは、以下のGIFアニメのように、[Pixabay](https://pixabay.com/)の[API](https://pixabay.com/api/docs/)を通して非同期で画像を検索・ダウンロード・表示します。

![Screen Record](https://yoichitgy.github.io/images/post/2015-08/SwinjectMVVMExampleScreenRecord.gif)

ソースコードは[GitHub](https://github.com/Swinject/SwinjectMVVMExample)のリポジトリからダウンロードできます。

## MVVM

MVVM (Model-View-ViewModel)とは、ViewはViewModelに依存し、ViewModelはModelに依存するという、線形でシンプルな依存関係を持つアーキテクチャあるいはパターンのことです。逆に、イベントの流れはModelからViewModel、ViewModelからViewへと一直線になります。

![Diagram-MVVM.png](https://qiita-image-store.s3.amazonaws.com/0/86677/6861d973-2f15-a3e7-d846-045b7dabdac5.png "Diagram-MVVM.png")

一方で、MVC (Model-View-Controller)型のアーキテクチャあるいはパターンでは、ControllerがModelとViewに依存し、イベントはModelからController、およびViewからControllerへと流れます。

![Diagram-MVC.png](https://qiita-image-store.s3.amazonaws.com/0/86677/ca709de8-a8dd-beab-57cb-3c91b2fea700.png "Diagram-MVC.png")

MVCの問題は、プロジェクトの開発が進むにつれ、Controllerが大きく複雑になりがちなことです。その原因は、ControllerがModelとViewの両方 (つまりすべて) の面倒を見てしまうことです。MVCは、実際にウェブアプリケーションの分野では[Ruby on Rails](http://rubyonrails.org/)や[ASP.NET MVC](http://www.asp.net/mvc)などのフレームワークのサポートがあり良いパターンなのですが、iOSアプリの分野では、MVCは一枚岩でメンテナンスしにくいコードに陥りやすいです。

MVCのその欠点のため、モバイルアプリあるいはデスクトップアプリを開発する上でMVVMが人気になってきています。iOSアプリでは、MVVMの "View" は "View" (UIView) と "ViewController" (UIViewController) から成り立ちます。Viewのロジック (`1000`という値を`"1,000"`と表示するなど) はViewModelに実装されます。Viewは単純にViewModelから提供される値を表示します。Modelはビジネスロジックに対して責任を持ちます。このように責任を分離することにより、MVVMアーキテクチャのiOSアプリはテストしやすくなります。

![Diagram-MVVM-iOS.png](https://qiita-image-store.s3.amazonaws.com/0/86677/f77b25f4-df83-cb33-1605-47c32dd68117.png "Diagram-MVVM-iOS.png")

### 参照

- [Introduction to MVVM](https://www.objc.io/issues/13-architecture/mvvm/)
- [ReactiveCocoa and MVVM, an Introduction](http://www.sprynthesis.com/2014/12/06/reactivecocoa-mvvm-introduction/)
- [MVVM Tutorial with ReactiveCocoa: Part 1/2](http://www.raywenderlich.com/74106/mvvm-tutorial-with-reactivecocoa-part-1)

## ReactiveCocoa

MVVMでは、ModelからViewModel、ViewModelからViewへとイベントを伝播させます。このシリーズでは、イベントを扱うためにReactiveCocoaを使用します。ReactiveCocoaはイベントのストリームを構成し、変換するためのAPIを提供します。ReactiveCocoaがない場合、イベントはデリゲートメソッド、コールバッククロージャ、UIControlのアクション、KVO (Key-Value Observation) などで表現されます。そのため、それぞれのイベントのタイプにより、別々の方法でイベントハンドリングする必要がありました。ReactiveCocoaがある場合、イベントは`Event`型で表現され、イベントのストリームは`Signal`あるいは`SignalProducer`で表されます。元のイベントの種類に関わらず、抽象化された同一の方法でイベントを扱うことができるようになります。この先の記事では、ReactiveCocoaでシンプルになったイベントを利用していきます。もしReactiveCocoaをこれまで使ったことがなければ、次の記事に進む前に以下のリンク先を読むことをお薦めします。

### 参照

- [ReactiveCocoa](https://github.com/ReactiveCocoa/ReactiveCocoa)
- [Framework Overview](https://github.com/ReactiveCocoa/ReactiveCocoa/blob/master/Documentation/FrameworkOverview.md)
- [A First Look at ReactiveCocoa 3.0](http://blog.scottlogic.com/2015/04/24/first-look-reactive-cocoa-3.html)

## まとめ

MVVMでは、ViewからViewModelへ、ViewModelからModelへと向かう依存関係を持ち、逆にイベントはModelからViewModelへ、ViewModelからViewへと流れるシンプルで線形的なアーキテクチャです。ReactiveCocoaは、デリゲートメソッドやコールバッククロージャなど多様な形のイベントをひとつの`Event`型のイベントに抽象化します。MVVMアーキテクチャとReactiveCocoaを利用したiOSアプリはシンプルに保つことができるため、メンテナンスやテストをしやすくなります。[次回のブログ記事](http://qiita.com/yoichitgy/items/ab9a3c019b4e3e89c63d)からは、MVVM、ReactiveCocoa、dependency injectionそしてSwinjectを利用した開発を順を追って説明していきます。

[^訳注1]: 訳注: 英語版の著者本人による翻訳のため、翻訳に関わる著作権上の問題はありません。