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

ΤϯδχΞืूத ͓ؾܰʹ࿈བྷ͍ͩ͘͞ʂ