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

【Android】<Kotlin>Repositoryパターンの役割と使い所とは?実装例をもとにわかりやすく解説

【Android】<Kotlin>Repositoryパターンの役割と使い所とは?実装例をもとにわかりやすく解説
すだ

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

本日は、
Androidアプリ開発におけるRepositoryの役割や必要性について
実際のコードを用いて解説します。

この記事を読んでわかること…
・Repositoryとは
・Androidアプリ開発におけるRepositoryを使用した実装例

目次

環境

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

「Repository(リポジトリ)」という考え方について

「Repository(リポジトリ)」という考え方は、KotlinやAndroidに限らず、他の多くの開発言語やプラットフォームでも共通して使われている設計パターン(=ソフトウェアアーキテクチャの考え方)の一つです。

Repositoryは主にデータの取得や保存の窓口となるクラスとして実装されます。

アーキテクチャの図を見るとわかりやすいですが、
異なるデータの出所をまとめて扱えるようにするための仕組みです。▼

【Android】<Kotlin>Repositoryパターンの役割と使い所とは?実装例をもとにわかりやすく解説
画像引用元:https://qiita.com/koutalou/items/07a4f9cf51a2d13e4cdc

API や データベース(DB) にアクセスする際は、直接アクセスするのではなく、Repositoryという「窓口」クラスを経由するイメージです。
Repositoryを使うことで、データの取得元を意識せずに使える構造が実現できます。

Repositoryを使った実装例

それではここで、APIで取得したデータをUIへ反映する処理の流れを Repositoryを使って書いていきます。

構成イメージ:

UserApi(Retrofit) → UserRepository → UserViewModel → Activity(UI)

①APIインターフェースとデータモデル

interface UserApi {
    @GET("users")
    suspend fun getUsers(): List<User>
}

data class User(
    val id: Int,
    val name: String,
)

APIクライアント

object ApiClient {
    val userApi: UserApi by lazy {
        Retrofit.Builder()
            .baseUrl("https://example.com/api/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(UserApi::class.java)
    }
}

APIクライアントは、APIとやりとりするための準備が整った通信装置のことです。
create(UserApi::class.java) を呼ぶとUserApi動的に実装したオブジェクト(匿名クラス) を作る、
そしてその実装インスタンスを val userApi にセットしています。
つまり、

val userApi: UserApi = Retrofitが作ったUserApiの実装クラス

ということになります。

③Repository

class UserRepository(private val api: UserApi) {

    suspend fun fetchUsers(): List<User> {
        return api.getUsers()
    }
}

UserRepository のコンストラクタに ApiClient.userApi が渡されたタイミングで、object ApiClientuserApi プロパティが初期化されます。
その結果、interface UserApi を実装したオブジェクトが生成され、
UserApigetUsers() メソッドを呼び出すことで、実際の API 通信が行われる仕組みです。

↑この「APIクライアントとの窓口」の役割を担うのが Repository です。
Userに関する API が複数に増えた場合も、それぞれの処理をこの 1 つの Repository にまとめて実装します。

④ViewModel

class UserViewModel(private val repository: UserRepository) : ViewModel() {

    val users = liveData {
        try {
            val result = repository.fetchUsers()
            emit(result)
        } catch (e: Exception) {
            emit(emptyList()) // エラー時は空リスト
        }
    }
}

※ ViewModelFactoryが必要ですが記述は省略します

⑤MainActivity

class MainActivity : AppCompatActivity() {

    private lateinit var viewModel: UserViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val textView = TextView(this)
        setContentView(textView)

        val apiClient = ApiClient.userApi
        val repository = UserRepository(api)
        val factory = UserViewModelFactory(repository)
        viewModel = ViewModelProvider(this, factory)[UserViewModel::class.java]

        viewModel.users.observe(this) { users ->
            textView.text = users.joinToString("\n") { "${it.id}: ${it.name}" }
        }
    }
}

最後に、呼び出し側の処理では、
ApiClientuserApi プロパティを注入して UserRepository のインスタンスを生成し、
それをさらに ViewModel に渡す(注入する)という構成になります。

まとめ

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

Androidアプリ開発におけるRepositoryは、API 通信処理やローカルDBとのやりとりなどが発生する開発場合、ほとんど必ず使うかと思います。
ぜひ覚えて開発に取り入れてください!

すだ

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

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

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

この記事を書いた人

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

コメント

コメントする

目次