【正社員】還元率83%【フリーランス】マージン一律5万円で案件をご紹介させていただきます。 詳細はこちら

【Android】<Kotlin>アプリ開発におけるMVPアーキテクチャ入門

【Android】<Kotlin>アプリ開発におけるMVPアーキテクチャ入門
すだ

みなさまこんにちは〜!
メモリアインクのすだです。

本日は、
Androidアプリ開発における「MVP」と呼ばれるアーキテクチャの基本について、実際のコードを用いて解説していきます!

この記事を読んでわかること…
・MVPというアーキテクチャについて
・MVPでの実装方法

目次

環境

  • Kotlin (ver 1.9.0)
  • Android Studio (Giraffe | 2022.3.1 Patch 3)

MVPとは?

MVP(Model-View-Presenter)は、Androidアプリ開発においてよく使われるアーキテクチャパターンのひとつです。

「画面表示のロジック」と「データの処理ロジック」を明確に分けることで、
保守性テストのしやすさが向上します。

MVPの3つの役割

Model(モデル)
アプリ内のデータ処理ビジネスロジックを担当します。たとえばAPI通信やDB操作など。

View(ビュー)
ユーザーインターフェース(UI)部分。ActivityFragmentがこれにあたります。

Presenter(プレゼンター)
ModelとViewの橋渡し役。ユーザーの操作に応じて、Modelに命令を出し、結果をViewに渡します。

【Android】<Kotlin>アプリ開発におけるMVPアーキテクチャ入門

なぜMVPが必要なのか?MVCとの比較

まず前提として、「アーキテクチャの目的」は各役割の「責任」を明確に分けることです。
これによって、バグが起きにくくなる修正がしやすくなるテストがしやすくなるといったメリットがあります。

比較1:View(画面表示部分)の責務

・MVCでは、ActivityFragmentViewとControllerの両方の役割を持ちがちです。
そのため、「UIの表示」も「イベントの処理」も「データ取得」も全部ここに書かれてしまい、肥大化(Fat Activity)になりがちです。
(AndroidではControllerが明確に存在しないため、結局ActivityFragmentがViewとControllerを兼ねることが多い)

・一方MVPでは、ActivityFragment表示だけに集中
たとえば「ボタンが押されたらどうするか?」というロジックは、Presenterが担当します。

【MVC】
    [Activity]  ⇄  [Model]
       ↑ ↓
     View + Controller混在
     
【MVP】
    [View(Activity)]
        ↓↑
     [Presenter]
        ↓↑
      [Model]

比較2:テストのしやすさ

・MVCでは、UIのコードにロジックが混ざっているため、
テストを書くにはUIも再現する必要がある=手間が多い&壊れやすい。

・MVPでは、Presenterがロジックだけを持っていて、Viewとの通信はインターフェース(interface)経由
このため、テスト時にはモック(仮のView)を使ってテストができます。

比較3:Androidとの親和性

Androidでは、公式に「Controller」という概念が明確に提供されていないため、MVCをそのまま使うのは実は少し難しいです。
MVPは「Presenter」という中間役を自分で作れるので自由度が高く、Androidに合わせやすいのです。


MVPMVVMが「UIの構造に関する設計パターン」であるのに対し、
クリーンアーキテクチャは「アプリ全体の依存関係と責務分離のための原則」ということになります。

MVVMやクリーンアーキテクチャの設計については以下の記事で詳細を説明しておりますので、ぜひ合わせてご覧ください!↓

サンプル処理で学ぶMVP実装(Kotlin)

それでは、MVPアーキテクチャを採用して「画面にあるボタンを押下するとメッセージがトースト表示される」という簡単な処理を作ってみます。

図でまとめると以下のような流れになるようにします。

[ MainActivity (View) ]
        ↑     ↓
     show / click
        ↑     ↓
[ MainPresenterImpl ]
        ↑     ↓
    getMessage()
        ↑     ↓
[ MessageModelImpl (Model) ]

前提理解①:
インターフェース(interface)とは?
「何ができるか(振る舞い・機能)」を約束するだけの設計図です。
中身(実装)は書かず、どんな関数を持つべきかだけを定義します。

前提理解②:
クラス(class)とは?
具体的な設計と中身(処理)が入った部品です。
変数や関数を持ち、実際の振る舞いやデータを定義できます。

View

インターフェイスの実装

// Viewに期待する操作を定義する「契約」インターフェース
interface MainView {
    fun showMessage(message: String)
}

Activityの実装

class MainActivity : AppCompatActivity(), MainView {

    private lateinit var presenter: MainPresenter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Presenterに自分(View)とModelの実装を注入
        presenter = MainPresenterImpl(this, MessageModelImpl())

        findViewById<Button>(R.id.button).setOnClickListener {
            presenter.onButtonClick()
        }
    }

    // ViewがUIを表示する処理
    override fun showMessage(message: String) {
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
    }
}

↑ここでユーザーのアクションをクリックリスナーで検知し、ボタン押下後の処理をPresenterに委ねます。

Presenter

インターフェイスの実装

interface MainPresenter {
    fun onButtonClick()
}

Presenterの実装

// Presenterの中身(ロジック)を実装
class MainPresenterImpl(
    private val view: MainView,
    private val model: MessageModel
) : MainPresenter {

    override fun onButtonClick() {
        val message = model.getMessage()
        view.showMessage(message)
    }
}

↑ここでPresenterは、UIからのイベント通知(ボタンクリック)を受け取ってModelを通して必要なデータを取得し、
それをViewに渡してUI表示を更新させるという一連の処理を担います。

Model

インターフェイスの実装

// データの取得や処理を定義
interface MessageModel {
    fun getMessage(): String
}

Modelの実装

// 実際のデータ処理の中身
class MessageModelImpl : MessageModel {
    override fun getMessage(): String {
        return "こんにちは!"
    }
}

↑今回はただ文字列を返しているだけですが、他にも以下のような処理を行います。
・Web APIとの通信(Retrofitなど)
・データベースの読み書き(Roomなど)
・ファイルアクセス
・データ加工や整形
・キャッシュ処理 など

まとめ

おつかれさまでした。いかがでしたでしょうか!

たとえ小さなアプリでも、MVPの考え方を取り入れておくことで、後の機能追加や保守がとても楽になります。

まずはこのサンプルのようなシンプルな構成から始め、徐々に応用してみてくださいね!

すだ

技術者としてのキャリアパスを次のレベルへと進めたい皆様、
未経験からIT・Webエンジニアを目指すなら【ユニゾンキャリア】
を通じて、
自分の市場価値をさらに向上させてみませんか?

それではまた次回の記事でお会いしましょう!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

弊社テックブログをご愛読いただきありがとうございます。
当テックブログを運用している株式会社メモリアインクは、
【正社員】還元率83%
【フリーランス】マージン一律5万円で案件のご紹介
と、エンジニアの皆様に分かりやすい形で稼げる仕組みを構築し提供させていただいております。

コメント

コメントする

目次