アプリのための「レイヤー化」アーキテクチャ / Droid Meetup 2019-03
by
Motoi Washida
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
アプリのための 「レイヤー化」アーキテクチャ RoomClip 株式会社 鷲⽥ 基
Slide 2
Slide 2 text
⾃⼰紹介
Slide 3
Slide 3 text
⾃⼰紹介 名前: 鷲⽥ 基 Twitter: @wm3 DroidKaigi スタッフ (Webサイト) RoomClip アプリエンジニア
Slide 4
Slide 4 text
Slide 5
Slide 5 text
RoomClipアプリのコードの パッケージ構成の話をします
Slide 6
Slide 6 text
Slide 7
Slide 7 text
皆さんに質問
Slide 8
Slide 8 text
パッケージをどの⽅向 で分割してますか?
Slide 9
Slide 9 text
アーキテクチャーの要素で分割
Slide 10
Slide 10 text
機能で分割
Slide 11
Slide 11 text
機能+アーキテクチャーの要素で分割
Slide 12
Slide 12 text
機能+アーキテクチャーの要素で分割2
Slide 13
Slide 13 text
Slide 14
Slide 14 text
Slide 15
Slide 15 text
RoomClip の場合
Slide 16
Slide 16 text
当初のパッケージ構成
Slide 17
Slide 17 text
当初のMVCパッケージ構成
Slide 18
Slide 18 text
models, views, controllers で分離 アーキテクチャーの要素による分類 クラス種類によるサブ階層 models/entities, controllers/activities など 当初のMVCパッケージ構成
Slide 19
Slide 19 text
課題
Slide 20
Slide 20 text
問題: あらゆる所で使われる 巨⼤エンティティ
Slide 21
Slide 21 text
例: 写真エンティティ
Slide 22
Slide 22 text
プロパティが30くらい 写真関連の属性が全部⼊っている ユーザーがその写真をいいねしたかとか 写真情報を渡す時はいつも使う 例: 写真エンティティ
Slide 23
Slide 23 text
すると
Slide 24
Slide 24 text
⼀部しか使わない属性が増える 属性に正しい値を⼊れなくなる 例: IDしか正しい値が⼊っていない 正しい値が⼊っているとは限らな い! あらゆる所で使われる巨⼤エンティティ
Slide 25
Slide 25 text
すると 例えば新機能開発時に
Slide 26
Slide 26 text
属性値が正しいのか分からない ソース追ったり実⾏しないと確認できない 新しい画⾯で使って良いのかわか らない あらゆる所で使われる巨⼤エンティティ
Slide 27
Slide 27 text
この属性 使っていいの?
Slide 28
Slide 28 text
問題: ⼀つのパッケージに クラスがずらっと並ぶ
Slide 29
Slide 29 text
単純に⾒通しが悪い クラスの公開範囲がわからない あらゆる所で使う事を想定したクラス ⼀箇所でしか使わないクラス ⼀つのパッケージにクラスがずらっと並ぶ
Slide 30
Slide 30 text
このクラス 使っていいの?
Slide 31
Slide 31 text
現在のパッケージ構成
Slide 32
Slide 32 text
現在の基本構成
Slide 33
Slide 33 text
レイヤー化されたパッケージ構成 ⼀部の例外除き逆⽅向の「依存」を許容しない 抽象的な要素は極⼒導⼊しない interface を集めたパッケージなど パッケージ構成の⽅針
Slide 34
Slide 34 text
共通パッケージ common.*, infrastructure.*
Slide 35
Slide 35 text
アプリの機能に依存しないコード ユーザー関連機能とかは基本⼊れない common 社内の別アプリで使いま わせるレベル design、api、trackingなど infrastructure 公開可能なレベル いつも使う utility など 共通パッケージ(common, infrastructure)
Slide 36
Slide 36 text
各機能のパッケージ app.*
Slide 37
Slide 37 text
アプリ特有のロジック 写真投稿、ホーム、など 機能毎にパッケージを分離 app.photo.post、app.social.home、など 各機能のパッケージ(app)
Slide 38
Slide 38 text
これだけだと 問題がある
Slide 39
Slide 39 text
パッケージ構成
Slide 40
Slide 40 text
パッケージ構成
Slide 41
Slide 41 text
問題: app の各パッケージが ⼤きくなる
Slide 42
Slide 42 text
コード全体が⼤きいのは仕⽅がな い ただし他の機能からの⼊り⼝は最 ⼩限にしたい 例: 投稿画⾯とかは遷移機能だけ公開すれば良い app 以下のパッケージが⼤きくなる
Slide 43
Slide 43 text
app/*/external 公開パッケージ app/*/internal ⾮公開パッケージ ほとんどのクラスは internal にする 対策: external/internal分離
Slide 44
Slide 44 text
問題: 横断的に管理したい 機能がある
Slide 45
Slide 45 text
機能横断した⽅が良いコードがある URL Handlerや計測 コード⽣成しているクラスがある API 関係 (参考: 去年のDroidKaigiのRejectConf) 横断的に管理したい機能がある
Slide 46
Slide 46 text
app/system/* URL Handlerなど 他の app パッケージと違い基本 external generated API レスポンスなど 対策: 例外的に機能横断的なものを管理するパッケージを⽤意
Slide 47
Slide 47 text
ドメイン特有ではあるが、ロジッ クは単純 宣⾔的なコードが多い 要素の定義が中⼼であり、実装関連のコードは⼊ らない 横断的機能のパッケージの特徴
Slide 48
Slide 48 text
パッケージ構成
Slide 49
Slide 49 text
結論
Slide 50
Slide 50 text
「レイヤー化」された パッケージ構成を 適⽤した
Slide 51
Slide 51 text
Slide 52
Slide 52 text
ΤϯδχΞืूத ͓ؾܰʹ࿈བྷ͍ͩ͘͞ʂ