2023/06/15開催、NIKKEI Tech Talk #8登壇資料です #nikkei_tech_talk タイトルは「日経電子版 for Android におけるドメインレイヤ(ユースケース)の実装方針について」です https://nikkei.connpass.com/event/284090/
2023/6/15横山朝海(@yokomii)日経電子版 for Androidにおけるドメインレイヤ(ユースケース)の実装方針についてNIKKEI TECH TALK #81
View Slide
2ドメインレイヤ
ハッシュタグ #nikkei_tech_talk● クリーンアーキテクチャやオニオンアーキテクチャにおけるドメイン層のことではありません🙇● Androidの推奨アーキテクチャガイドラインにおけるドメインレイヤです○ https://developer.android.com/topic/architecture/intro○ 日経電子版 Androidアプリではこの推奨アーキテクチャを設計の基本指針としていますドメインレイヤ3
ハッシュタグ #nikkei_tech_talkAndroid 推奨アーキテクチャ4● 推奨アーキテクチャにおける共通原則○ 関心の分離○ 永続データモデルによるUI操作○ SSOT○ 単方向データフロー(UDF)● 上記共通原則を考慮した上で、2層(UI、データ)以上のレイヤードアーキテクチャを推奨○ ドメインレイヤはオプショナル
ハッシュタグ #nikkei_tech_talkデータレイヤ5● アプリデータの作成、保存、変更のためのビジネスロジック群● データソース○ アプリとシステム(ネットワーク、ローカルDBなど)間のデータの橋渡しをする● リポジトリ○ データ管理のためのビジネスロジックを有する○ 上位レイヤにデータを公開する
ハッシュタグ #nikkei_tech_talkUIレイヤ6● データレイヤから取得したデータを表示するためのレイヤ● UI状態ホルダ(ViewModel)○ 下位レイヤからデータの取得○ UI状態の生成・保持○ UI操作によって適切なビジネスロジックを呼び出す● UI要素(View、Jetpack Compose)○ UIをレンダリング
ハッシュタグ #nikkei_tech_talk🌟ドメインレイヤ7● UIレイヤとデータレイヤの間に位置するレイヤ● 複雑なビジネスロジックや、複数のUI状態ホルダで再利用される単純なビジネスロジックをカプセル化した「ユースケース」クラスを内包
ハッシュタグ #nikkei_tech_talkユースケース8● ビジネスロジックをカプセル化したクラス○ 1ビジネスロジックにつき1クラスの単位で実装● その他ガイドライン上の推奨事項○ 命名規則■ 動詞の現在形 + 対象 + UseCase○ ライフサイクルを持たない■ 毎回新しいインスタンスを生成■ 状態(可変データ)を持たない○ メインセーフ
ハッシュタグ #nikkei_tech_talkユースケース9● ユースケースクラスを設ける利点○ 共通ロジックをカプセル化することでボイラープレートコードの回避○ ロジックを外部クラスに切り出すことで、ケースを使用するクラスの可読性の向上○ 1クラスで1ビジネスロジックだけに集中することでコードがシンプルになり、テストが書きやすい
ハッシュタグ #nikkei_tech_talkユースケース10● システムの振る舞いの中核を担う、クリーンアーキテクチャのユースケースとは別物● あくまでビジネスロジックをカプセル化することで、コードの複雑さを減らすことが目的● 推奨事項がいくつか存在するが、様々なアプリに適用しやすいようにあえて厳格なルールは設けられていない⇨自由実装になりがち● 👉 ガイドライン以上の細かな方針を各アプリで定めることが重要!!https://developer.android.com/jetpack/guide/domain-layer
11日経電子版 for Androidにおけるユースケースの実装方針🧭(推奨ケース・非推奨ケース)
12🙆推奨ケース
ハッシュタグ #nikkei_tech_talk🙆推奨ケースその113複数リポジトリ処理を組み合わせる● (公式ガイドラインでも紹介されているケース)● 複数リポジトリからの取得値を別の値に変換して返すなど● ユースケースはUIレイヤとデータレイヤの間に位置するので、UI状態ホルダとリポジトリの中継処理をすることが多い
ハッシュタグ #nikkei_tech_talk🙆推奨ケースその214単一リポジトリ内の複数処理を組み合わせる● (このようなビジネスロジックは大体リポジトリ側で吸収できるはず)● アプリ特有の関数の実行手順がある場合などにユースケースで吸収○ 例えばWearとモバイルで共通のリポジトリを用いているが、リトライ回数に違いがあるときなど
ハッシュタグ #nikkei_tech_talk🙆推奨ケースその315再利用されるビジネスロジック● (公式ガイドラインでも紹介されているケース)● UIレイヤで繰り返し発生するロジックをビジネスロジックとしてカプセル化する● 公式ガイドではUtilクラスの代替としてユースケースを用いることを推奨○ Utilクラスは1クラスに複数ビジネスロジックが含まれることで肥大化し煩雑になりがち○ 反面ユースケースは1クラス1ロジックかつ、クラス名によって処理内容が明瞭
16🙅非推奨ケース
ハッシュタグ #nikkei_tech_talk🙅非推奨ケースその117リポジトリの関数を呼ぶだけのケース● UIからリポジトリの直接参照を禁止する場合に、その中継を担うためのケース● リポジトリ参照を制限をするメリット○ UIでデータ取得する際に必ずユースケースを経由するのでコードの一貫性が保たれる○ リポジトリに含まれる全ての関数がUIに公開されなくなる
ハッシュタグ #nikkei_tech_talk🙅非推奨ケースその118リポジトリの関数を呼ぶだけのケース● 日経電子版のデータレイヤの特徴○ 扱うデータの種類が多い○ リポジトリの関数の種類が多い■ サービスを長期運用する中でどんどん数が増えていった● 関数呼び出しごとにクラスを設けた場合にクラス数が膨大になりすぎる○ 先にデータやリポジトリ関数の整理が必要● ↑のため、UI状態ホルダがリポジトリを直接参照することを制限せず、このようなケースは一旦不要とした
ハッシュタグ #nikkei_tech_talk🙅非推奨ケースその219モデルデータをUI状態に変換● UI状態 = モデルデータをUIがレンダリングしやすい形式に加工した状態○ ref:https://developer.android.com/topic/architecture/ui-layer#define-ui-state● UI状態をカプセル化したクラスはUIレイヤに定義している○ 下層であるドメインレイヤからは参照できない● よってUI状態はUIレイヤの関心ごと⇨変換はUIレイヤでやる
ハッシュタグ #nikkei_tech_talk🙅非推奨ケースその320Resultクラスを戻り値とするビジネスロジック● 当初、kotlin.Resultや自作のResultクラスで実行結果をラップして値を返すようなケースを認めていた● ←のようなコードでは、CancellationExceptionを握りつぶしてしまうので呼び出し元のコルーチンが正常に中断されなくなる● 意図しないキャンセル例外の握りつぶしを防ぐためにResultクラスの利用は非推奨とした○ FYI: kotlin-resultにはrunSuspendCatching()というこの問題を回避する仕組みがある
ハッシュタグ #nikkei_tech_talk● Androidの推奨アーキテクチャは幅広いアプリ(iOSも👍)に適用しやすいように、あえて厳密にルール化されていない部分がある○ そのため、各アプリでより詳細な方針を定めることが重要● 今回紹介した方針はあくまで電子版における内容であり、全てのアプリにおいて最適解ではないことをご留意ください○ 開発規模や要件によって最適な戦略を探る🧐● アプリ独自の方針が公式ガイドラインの指針から大きく外れないことを推奨○ 公式の情報はエンジニア間で共通認識となりやすいので、そこに揃えておくと読み解きやすいコードになる● 皆さんの開発してるアプリでのユースケースの実装方針もぜひ教えてください🫶まとめ21
22ご清聴ありがとうございました🧏