翻訳者から:この記事は、開発パターンに関する英語の記事の改訂版です。 適応の過程で、多くをロシア語に変更する必要がありました。 オリジナル
さまざまな開発パターンの選択には常に一連の論争と議論が伴い、これに関する開発者のさまざまな見解がタスクをさらに複雑にします。 このイデオロギーの問題の解決策はありますか? MVC、MVP、MVVM、およびMVIについて実用的に話しましょう。 「なぜ?」、「コンセンサスを見つけるには?」という質問に答えましょう。
エントリー
MVC、MVP、MVVM、MVIのいずれを選択するかという質問は、チームでWarta Mobileのアプリケーションを作成するときに感動しました。 最小限の実行可能製品から、実績のある完全装備のアプリケーションに移行する必要があり、何らかのアーキテクチャを導入する必要があることを知っていました。
多くの人は、さまざまな開発パターンについて揺るぎない意見を持っています。 しかし、MVCなどのアーキテクチャを考えると、それは完全に標準的で特定の要素であるように思えます。モデル、ビュー、コントローラー、さまざまな人々がさまざまな方法で説明します。
Trygve Reenskaug-MVCの発明と定義。 それから24年後、彼はそれをアーキテクチャとしてではなく、MVCのアイデアに基づいた一連の実際のモデルとして説明しました。
各プロジェクトはユニークであるため、完璧なアーキテクチャはないという結論に達しました。
さまざまな実装方法を詳細に検討し、それぞれの利点と欠点を考慮する必要があります。
何を達成したいですか?
スケーラビリティ、保守性、信頼性
明らかに、 スケーラビリティとは、プロジェクトを拡張し、新しい機能を実装する機能です。
保守性 -すべての機能が実装された後、小さなアトミックな変更の必要性として定義できます。 たとえば、ユーザーインターフェイスの色が変更される場合があります。 プロジェクトの保守性が高いほど、新しい開発者がプロジェクトをサポートしやすくなります。
信頼性 -不安定なアプリケーションに神経を浪費する人はいないことは明らかです!
共同責任、コードの再利用、テスト容易性
ここで最も重要な要素は、懸念の分離です。 異なるアイデアを分離する必要があります 。 何かを変更したい場合は、コードの別の部分に移動しないでください。
責任を共有しなければ、 コードの再利用性もテスト 性も実装することはほぼ不可能です。
重要なのは、ボブおじさんがClean Architectureで述べたように、 独立です。 たとえば、画像をアップロードするためにライブラリを使用する場合、最初に作成された問題を解決するために別のライブラリを使用する必要はありません! アプリケーションアーキテクチャの独立性-スケーラビリティと保守性を部分的に実装します。
モデルビューコントローラー
MVCアーキテクチャには、 監視コントローラーとパッシブビューの 2つのオプションがあります。
モバイルエコシステムでは、スーパーバイザーコントローラーの実装はほとんど見当たりません。
MVCアーキテクチャは、2つの方法で特徴付けることができます。
- ビューはモデルの視覚的な投影です
- コントローラーは、 ユーザーとシステムの間の接続です。

この図は、パターンのイデオロギーを示しています。 ここで、パフォーマンスはリスナーとコールバックの両方を定義します。 ビューは入力をコントローラーに渡します。
コントローラは入力を受け入れ、プレゼンテーションは出力を受け入れますが、それらの間で多数の操作が発生します。 このアーキテクチャは、小規模なプロジェクトにのみ適しています。
パッシブMVCビュー

パッシブMVCビューの主な考え方は、ビューがコントローラーによって完全に制御されるということです。 さらに、コードは明らかにビジネスロジックと表示ロジックの2つのレベルに分かれています。
表示ロジック-アプリケーションの外観
大規模なView Controller
アクティビティをビューとして解釈することはできません 。 これを表示レイヤーと見なす必要があり、コントローラー自体を別のクラスに配置する必要があります。
また、View Controllerのコードを削減するために、ビューを分割するか、独自のControllerでサブビューを定義できます。 この方法でMVCパターンを実装すると、コードをモジュールに簡単に分割できます。
ただし、このアプローチでは、いくつかの問題が発生します。
- ディスプレイロジックとビジネスロジックの組み合わせ
- テストの難しさ
これらの問題の解決策は、プレゼンテーション用の抽象的なインターフェースを作成することにあります。 したがって、プレゼンターはプレゼンテーション自体ではなく、この抽象化でのみ動作します。 テストは簡単で、問題は解決します。
これがすべてMVPの主なアイデアです。
モデルビュープレゼンター
ビューは複数のインターフェイスを実装できるため、このアーキテクチャは単体テストを容易にし、 プレゼンターはテストを簡単に記述でき、再利用することもできます。
インターフェイスを作成する方がより適切で正しいという観点から、MVPとMVCは開発パターンではなく主要なアイデアとしてのみ考慮する必要があります。

ユースケース
ユースケースの作成は、ビジネスロジックを個別のクラスに分けてモデルの一部にするプロセスです。 これらはコントローラーから独立しており、それぞれに1つのビジネスルールが含まれています。 これにより、再利用性が向上し、テストの記述が簡単になります。

GitHubの例では、ログインコントローラーで、検証のユースケースとログインのユースケースがレンダリングされます。 ログインがネットワークに接続します。 他のコントローラーまたはプレゼンターに一般的なビジネスルールがある場合は、これらのユースケースを再利用できます。
バインディングを表示
MVP実装には、ユーザーインターフェイスにわずかな変更を加えるだけの4つの線形関数があります。 ビューバインディングを使用すると、この余分なコードを回避できます。
バインディングのすべての方法は、 ここにあります 。
簡単なアプローチを次に示します。テストが簡単で、プレゼンテーション要素を機能としてではなくインターフェイスを通じてパラメーターとして提示するのがさらに簡単です。
発表者の観点からは、何も変わっていないことは注目に値します。
モデルビュービューモデル
別のバインド方法があります。ビューをインターフェイスにバインドする代わりに、ビューの要素をビューモデルのパラメーターにバインドします。このアーキテクチャはMVVMと呼ばれます。 この例では、電子メール、パスワード、およびマークアップのフィールドはバインディングを使用して定義されます。 モデルのパラメーターを変更すると、マークアップも変更されます。

ViewModelは、モックオブジェクトを記述する必要がないため、テストを簡単に記述できます。これは、独自の要素を変更してから、その変更方法を確認するためです。
モデルビューの意図
アーキテクチャに導入できる別の要素は、通常MVIと呼ばれます。

ボタンなどのマークアップ要素を使用する場合、ボタンはデータを生成すること、特に押されたかどうかの情報を送信すること以外は何もしないと言えます。
RxJavaライブラリでは、イベントを作成するものはobservableと呼ばれます。つまり、ボタンはリアクティブプログラミングパラダイムで観察可能になります。
ただし、TextViewはテキストのみを表示し、データを作成しません。 RxJavaでは、データのみを受け入れる要素はconsumerと呼ばれます。
これを行う要素、つまりTextEditなどの情報を送受信する要素もあります。 このような要素はプロデューサーとレシーバーの両方であり、RxJavaではsubjectと呼ばれます 。
このアプローチでは、すべてがストリームであり、各ストリームはプロデューサーが情報を発信し始めた瞬間から始まり、あるレシーバーで終わります。レシーバーは情報を受け取ります。 その結果、アプリケーションはデータストリームと見なすことができます。 データストリームはRxJavaの主なアイデアです 。
おわりに
責任の分離を実装することは努力ですが、コード全体の品質を向上させ、スケーラブルで理解しやすく、信頼性を高めるには良い方法です。
MVVM、定型コードの削除、MVIなどの他のパターンにより、スケーラビリティがさらに向上しますが、プロジェクトはRxJavaに依存します。
また、これらの要素の一部のみを選択し、タスクに応じて最終アプリケーション用に構成できることを忘れないでください。
すべてのソースはここにあります 。