Noblesse Oblige

App/iOS/Android/Unity/cocos2d/VR/GameJam/Hackathon/肉 ブログの記事は勉強会の書きなぐりメモが多め

【DroidKaigi 2017】大規模アプリのリノベーション

セッション情報

speakerdeck.com

発表者

  • Ryo Kitamura
  • hatena

大規模なアプリとは?

リファクタリングしたい

  • 単純にコードがあ大きい + 設計が統一されていな
  • 将来のセキュリティが心配
  • 片手間でやっていた頃もあった
    • 設計を十分に撮る時間がなかった
    • 置き換え切れない!
  • リファクタリングに専念する期間が必要
    • リノベーション

ドメイン知識の獲得

  • 昔から開発し続けている人はいない
  • 完璧なドメイン知識を誰も持っていない
  • チームメンバ共通のドメイン知識が必要

画面を知る

  • 歴史とと主に画面が増えた
  • どの画面から起動され、どんな画面が出るかを知る
    • 外部アプリから起動されたとき用の画面
    • ログインしていると内容が変わる画面
    • エラー時の画面
  • スクリーンショット撮りまくってGraphvizで繊維を可視化
    • 大きすぎるので紙に印刷してみんなで見た
  • 画面の詳細を詰める
    • 画面名
      • 本来の適切な名前はこうじゃないか?
    • Model
      • 本当はこういう名前じゃないか?
    • View
  • 画面情報をドキュメント化
    • githubにあげて検索できるようにする

デザイン意図の確認

  • 画面一覧はデザイナも見る
  • 各部のデザインの理由を知る
    • 必要ないところは削る
  • 準備の段階として必要
  • よく見ると似たものばかり、時間のフォーマットが違う…
    • でも理由はある
  • 理由を知っていくことで、各Viewに名前をつけていくことができる!

設計

  • ライブラリ選定
  • アーキテクチャの決定
  • サンプルアプリの作成
  • ドキュメント作成
  • 組み込む

ライブラリ選定

  • 使っても良さそうというのをあげていく
  • 設計で変わるため各地絵するのが目的ではない
  • とにかくあげまくる

アーキテクチャの決定

サンプルアプリの作成

  • 出来上がった設計を試す & 修正

設計

主なライブラリ

  • Dagger2
  • Realm
  • Retrofit2

主なレイヤー

  • MVVM

前提

  • 下のレイヤーは上のレイヤーは知らない
    • レイヤーの処理を外に漏らさない
  • 下のレイヤーが上のレイヤーに結果を伝える時はObserbableを使う
  • Dagger2でinjectする

Repository

  • EntryRepositoryならEntryに関わる処理を担当する
  • Interfaceとその実装を用意する
    • テストが用意
  • Repositoryを提供するDaggerのModuleを同じパッケージにもつ

Interactor

  • 内部にRepositoryを持つ
  • 必ずRxで返す
  • 変更可能な状態を持たない
    • キャッシュなどの役割はRepository
  • スレッドを決定する
    • 最後には必ずメインスレッドに戻す
    • Interactorを組み合わせない前提の設計

ViewModel

  • 内部にInteractorを持つ
  • ViewはViewModelのことを知っている
  • ViewModelはViewを知らない
  • Activity FragmentもViewとみなす
  • 内部に通知用Observableを持つ
    • 状態が変わると通知
  • Databindingで自身がLayoutoにセットされることも想定
  • (ある程度は) 使い回される前提

ViewModelの回想

  • ViewModelは階層を持つ (ことがある)

ViewModel Navigator

  • 繊維を表すクラス
    • ViewModelの中で作らず、外部から渡される
    • onClick自党の繊維で使われる

設計のドキュメント化

  • 作る前に攻勢をドキュメント化するう
    • 人の入れ替わりに備える
    • 設計をブレさせない
  • この設計になった理由も書く
    • 納得してもらうため
  • 概要、説明、サンプルコード、規約…

着手

  • 進め方
    • 画面毎にタスクを切る
      • ひとつ完成するのに時間がかかる
      • 見積もりにくい、分担しにくい
    • Repository -> Interactor -> Videmodelと進めていく
  • 置き換えかた
    • いきなり全部変更しない (破綻する)
    • RxJava2かは後回し (簡単ならやる)
    • 移行用パッケージに一時的なクラスを作る (移行後に消す)
    • Componentも少しずつ移動してく

リリース

  • 1、2週間ごとに様子を見てやる

まとめ

  • 着手前にドメイン知識を得る
  • レイヤーごとに分けて下からやっていく
  • 見積もる
  • 長くても2週間ごと
  • 設計はプロダクトによって千差万別
  • 良い設計を部分的に取り入れる
  • 完璧にするのは困難なので妥協点を見つけてやっていく