iOSの新規プロジェクトでClean Architecture + Application Coordinatorの構成にした理由と感触

# 経緯
今回良い縁に恵まれまして、
新規サービスでiOSアプリを作成させてもらったので、そのフィードバック用にQiitaの記事を書くことにしました。

で、今回のアプリは
Clean Architecture + Application Coordinator
の構成を採用しました。
シリーズものにしていこうと思っているので、興味があれば見ていってください。

で、今回第一弾としまして、なぜ
Clean Architecture + Application Coordinator
の構成にしたかを書こうと思います。

## なぜClean Architectureか？
大きな理由は、自分はもともとサーバーサイドJavaから開発をやり始めた人なので、コントローラ、サービスクラス、ロジッククラス、Daoと明確に機能を分けていくという構成が、Clean Architectureの概念に近かったので採用しました。
他のMVCやMVVMに比べて各クラスの機能が明確なため、誰が書いてもある一定ラインよりも上の品質でできあがるので、非常にやりやすかったです。

## 他の選択肢はなかったか？
RxSwiftも候補には上がっていて、全部それで書いてもよかったのですが、iOSは社員自分だけで、swiftも自分だけしか触ったことのないという状況で、導入する障壁が非常に高かったので諦めました。

## なぜApplication Coordinatorか？
ViewControllerのイベントに対して画面遷移を外から代入するという発想が良く、各Coordinatorごとの依存が明確なのが非常に良いと感じました。
今回は[以前書いた記事](http://qiita.com/takahia/items/67b9e1229682127d924e)のConfiguratorでDIを行う発想から、Factory PatternでDIを行い、Coordinatorから呼び出すことにしました。

## 他の選択肢はなかったか？
### StoryBoardで画面遷移は？
そもそも今回メインでStoryBoardを利用する気が全然ありませんでした。
理由は簡単でPull Requestの差分が発生した時の確認が非常に大変だからです。
しかしながら、Autolayoutの制約だけはLibraryを利用するとしても、コードで書くとかなりの量になるので、昔ながらのxibファイルに逃げました。
ただ、Top Layout GuideとBottom Layout GuideだけはStory Boardにしかないので、UINavigationControllerだけStoryBoardで生成しています。

### VIPERのWireframeは？
画面遷移がPresenter側寄りになるので、ぱっと見わかりづらいなぁと感じていました。
一般的にはViewController側で画面遷移をするので、それを外に出すならViewController寄りのApplication Coordinatorの方が直感的にわかりやすいと思いました。
直感的なわかりやすさは超大事！！

# 見えてきたメリット・デメリット
## Clean Architecture
### メリット
 - 個人のコーディング能力のバラツキをある程度抑えることができる
 今回、これが大きな良い誤算でした。
 基本的にはProtocolと一部機能だけ、例えばユーザ登録機能だけこちらで書いて、他の機能をこれらと同じルールで書いてとお願いするだけでそれなりのものが上がってきました。
 普段だと、各個人の裁量によってバラバラなコードが上がってくるとこが多いので、レビューも大変な思いをしてきたのですが、そのバラツキがある程度少なくなったことで、こちらのレビュー速度もあげることができたので、その点は非常に良かったです。

 - 同じ画面で違う動作をさせたいときに非常に便利
 今回同じ画面で違う経路から遷移した際、同じボタンイベントでそれぞれ
 ・APIをコールする
 ・Core Dataに保存する
 ということが必要でした。
 今回、同じViewControllerに対して、APIをコールするUseCaseを持つPresenterとCoreDataに保存するUseCaseを持つPresenterという異なるPresenterをViewControllerに代入することで、スマートに書けたと思います。

###デメリット
 - ファイル数が非常に多くなる
 規模にもよりますが、今回のプロジェクトは800弱のファイル数になりました。

 - それぞれ依存関係が明確なので、やりたいことに対して頭を捻ることが多くなる
 例えば、AppDelegateでUserDefaultを利用したいときが良くありますが、UserDefaultもData Layerになるので、直接呼び出すことができないため、AppDelegateUseCaseを作成し、AppDelegateUseCaseに仕事をさせる形で実現します。
 そこまでなら良いのですが、Application Coordinatorを採用している手前、AppDelegateUseCaseでUserDefaultの値を見て、View Controllerに何か動作させたいときに詰まりました。
 結局良い方法が思いつかなかったので、Notification Centerを利用する結果になりました。
 依存性がわかりやすいという理由も含めてClean Architectureを利用しているのに、依存性がわかりにくくなるNotification Centerを使ってしまったのは、後悔でしかないです。

##Application Coordinator
###メリット
 - 一連のフローを一つのCoordinatorにまとめれるため、依存が明確で、画面遷移を追いやすい。
 これが一番大きいと思います。
 例えば、ユーザ登録のCoordinatorは、ユーザ認証画面であったり、ユーザの情報登録であったり、その画面の各ボタンを押した時の画面遷移が全部同じCoordinatorでハンドルするので、デバッグが楽でした。
 - すぐに画面遷移だけを確認できる
 先にViewControllerにイベントのIFだけ書いて、Coordinator側で画面遷移だけを実装してすぐ確認が取れるため、画面遷移の確認や修正には工数がかからずに済みました。
　　また、修正対象の遷移を持つViewControllerに対して、
 書いた人以外の人がViewControllerのソースをじっくり読むことなく画面遷移の修正ができるので、その点も評価できます。

###デメリット
 - それなりの学習コストがかかる
 今回、Application Coordinatorを触ったことのある人がいなかったため、定着するまでに時間がかかりました。

 - 結構無茶な画面遷移ができてしまいます。
 ある画面フローに対して画面遷移を一箇所で行うため、結構無茶な画面遷移ができてしまいます。
 今までなら、”この画面フローをやるとコードが汚くなるためやめたいです”とできてたところが、結構なんでもできてしまうのです。
 下手をすればUXを損なう遷移も簡単に実装できてしまう危険があるので、そこを慎重に考えてApplication Coordinatorを利用していくのが重要だと感じました。

#総評
今回デメリットで上げたことを加味したとしてもメリットの方が勝ると感じました。
今後追加機能を導入する際に、新たなメリット・デメリットが出てくると思うので、そのときにまた記事を書ければと思います。

#参照
[まだMVC,MVP,MVVMで消耗してるの？ iOS Clean Architectureについて](http://qiita.com/koutalou/items/07a4f9cf51a2d13e4cdc)
[Introducing Application Coordinator](https://speakerdeck.com/andreypanov/introducing-application-coordinators)