プロジェクトにMVPアーキテクチャを採用して１年。導入背景と変遷を振り返る。

# はじめに
所属する会社のプロジェクトにMVPを導入して、1年とちょっとが経ちました。なぜMVPを導入したのか？導入してみて、解決できた問題はなにか？次の課題はなにか？といったことを振り返っておこうと思います。

そもそもMVPってどんなアーキテクチャなの？と言う方は以前にこのような記事も書いているのでぜひ読んでいただけたら嬉しいです。

https://qiita.com/Ri__/items/4ccd2dab642b2959aaf8

https://qiita.com/Ri__/items/e542bb88a7cd4243215a

# この記事でわかること
- 新規プロジェクトになぜMVPを採用しようと思ったのか
- MVPを採用して見えてきた課題
※既存のアーキテクチャをMVPに置き換える方法は分かりません


# MVPを採用した背景
## 当時の課題
MVP採用以前はMVCアーキテクチャを採用していました。
MVCを採用していたので例に漏れず、とてもFatなViewController状態になっており、処理の流れが追いづらい状態になっていました。

ボタンを押したら、ModelとViewControllerをなん往復もして、その途中でいろんな処理を行なって...みたいな感じになっていたり、通信後の成功したら〇〇、失敗したら△△のような処理がViewControllerに入り込んでいたり。

この`処理の追いにくさ`と言うのが当時の１番の課題だったと思います。

処理が追いにくいと、当然何かの変更を加えようと思った時に大量の時間を使います。また、思わぬところで変更が影響してバグを生み出したりもします。

*ここで言いたいのは当時このような課題があったというだけで、そのコードを書いたエンジニアを責める意図や、MVCを採用したことを責める気持ちは少しもありません。
MVCを採用した当時は別の問題を解決しただろうし、当時のエンジニアがプロダクトを作って、売り上げを立ててくれたからこそ、今僕らはこの会社で不自由なく働くことができていています。

## MVPを採用するに至るまで
ちょうどMVPを採用する直前に、新規プロジェクトが立ち上がるという話になり、これはMVCを変える良い機会だなと思い、色々なアーキテクチャを勉強していました。

そんな時に、とある企業のCTO、iOSテックリードの方とお話をさせてもらう機会があり、`「MVP採用するとPresenterが仕様書みたいになって処理の流れがわかりやすくなるよ！」`とアドバイスをいただきました。

Presenterを`仕様書`のようにできる、というのはまさに当時の課題を解決できる手段だと思い、「MVPを採用してこんな感じに書けば、処理の流れがわかりやすくなるっす！」と他のエンジニアにも説明したら賛同を得られ、採用になりました。

他にもVIPERやRx+MVVMなど候補はありましたが、やはり学習コストが高すぎたので、MVPを採用しました。

# MVPを採用して得たメリット
当初課題であった、`処理の追いにくさ`はかなり軽減されました。

Presenterを見るだけで、**Viewからどのようなイベントがやってくるのか**、**Viewのイベントとドメインロジックがどのように結びついているのか**、**どんな表示の指示をViewにしているのか**、これがパッと見えるのは処理の流れをかなり追いやすくしてくれました。

どのように書くと仕様書のように見立てられるかは以下の記事を読んでもらえればなんとなくわかるのではないかと思います。

https://qiita.com/Ri__/items/e542bb88a7cd4243215a

# MVPの変遷
MVPを採用することにより、Presenterを`仕様書`と見立て、処理の流れの見通しをよくするということにはある一定の成果を上げました。

しかし、まだまだ課題は出てきます。MVPを採用することでどのような課題が出てきたのか、そしてその課題にどのように立ち向かっているのかを紹介します。

## ViewController+Presenter+UseCase ver1.0時代
### 概要
MVPを採用し、Presenterを仕様書のように見立てること。とにかくそれを意識して書くようにしました。しかし、`M`の部分をどうしたら良いかということは全くわからなかったので以下のような形にしました。

1つのViewControllerに対して１つのPresenterと1つのUseCaseを持つ感じです。

![スクリーンショット 2023-04-01 12.41.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2644705/475bfe12-8cc1-478a-eae1-409808815203.png)

### 出てきた課題
1つのViewController（画面）に対して１つのUseCaseがあるので、当然のことながら処理が被ります。
Aという画面と、Bという画面でそれぞれ同じ処理を必要としているとき、画面ごとのUseCaseを作成しているので、どちらの画面のUseCaseにも`同じ処理`を書かなくてはいけません。

## ViewController+Presenter+UseCase ver.2.0時代
### 概要

ver1.0時代の課題である同じ処理を複数回書かなければいけないという問題を解決するために、UseCaseを機能単位に分けました。そうすることで、UseCaseを複数のPresenterで使うことができるようになり、同じ処理を書かなくてもよくなりました。

![スクリーンショット 2023-04-01 13.21.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2644705/4ab17a9d-7534-b329-224a-d7a2800d05ad.png)

### 出てきた課題
- 複数のUseCaseをPresenterが持つようになったので、PresenterがUseCaseまみれになってしまう
- Mの部分を全てUseCsaeが担っているのでクラスが肥大化してしまう
- APIの呼び出し処理が複数のUseCaseで重複してしまう。

## DataStore導入時代(今)
### 概要
UseCaseから通信の部分を切り離すことで、すべてのM部分をUseCaseが担当するのをやめました。
そして、複数のUseCaseから同じAPIを呼びやすくなりました。
大量のUseCaseをPresenterが抱えてしまう問題にはまだしっかりと対応ができていません...
![スクリーンショット 2023-04-01 13.43.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2644705/a2cb8150-393c-54e6-fd94-c79c458a067e.png)

### 今後の課題
少しずつ課題を解決できるようにはなってきて、以前よりもわかりやすくなってきたと思います。
でもまだまだ多くの課題があります。
- Presenterが大量にUseCaseを持ってしまう問題
- 現在の形になっていない過去のコードをいつ修正するのかという問題

そもそも、課題とは感じていないけど、それじゃまずいんじゃないのというところも含めてたくさんあると思いますが少しずつ改善をしていきたいと思います。


# MVPを採用して課題になることと対策
## 課題
変遷のところでも出てきましたが、MVPを採用して課題になるのは`M`をどのように分けるかという点です。

MVPはプレゼンテーション層とそれ以外をどう分けるかというところに対しての問題は解決できると思います。しかし、`M`の部分をどのように分けるかということに関しては言及されていません。

つまり、`M`をどうしていくかに関しては、MVPでは解決できず課題として残ります。
この他にも、MVVMやMVCもMVPと同様GUIアーキテクチャと呼ばれ、`M`の部分をどのようにすべきかの課題は解決できないように思います。


## 対策
対策と書きましたが自分自身まだまだ全然わかっていません。

ただ、この課題を解決するためには、クリーンアーキテクチャ、VIPERなどのシステムアーキテクチャ、DDD、SOLID原則など幅広く学ぶ必要がありそうです。

データの取得をする関数を書くのにも、コマンドクエリの法則に則って、データの取得とドメイン層に返す関数とを分けた方がいいのか？とか考えることは猛烈にたくさんあります。

まだまだ勉強できていない部分がたくさんあり、わからないことだらけですが少しずつ勉強したいと思っています。


# 新しいアーキテクチャを導入するという経験を経て感じたこと
アーキテクチャを導入すると言う経験を経て感じたことは、アーキテクチャは手段であり、目的ではないとうことです。
エンジニアになって新しいことを学ぶと、それを実際に使いたくなってしまうことがあります。

でも、それって本当に今のチームの、プロジェクトの何かの課題を解決する`手段`になってるの？ということは常に意識するべきだなと思います。
今抱えている課題を解決しないのであれば、それはただの自己満になってしまうと思います。

究極的にはそれで、会社に利益をもたらすのか？ということを考えるのが１番大事な気がします。
いくら綺麗なコードを書いても、そのプロジェクトが売り上げを生み出さなければ会社としては成り立ちません。

今抱えているコードの問題を解決するのが先か？新機能を付け足すのが先か？
利益を残すための手段はさまざまです。

エンジニアになってようやく1年と4ヶ月が経ちました。
まだまだ未熟もいいところなので、何が今のプロジェクトをよくする最善の一手なのかということを常に考えながら頑張っていきたいです。

# おわりに
まだまだ、勉強することたくさん。面白いっすね。
ちょっと参考になったぞーというかたはぜひ**いいね**を...してくれたらうれしいなぁ。

ではでは、おーわーり。