ワウテックAndroidアプリ担当の岡野です。今回は珍しくAndroidに関する投稿です。WowTalkには様々な機能がありますが、私が着任当時に実装した機能がタスク管理機能でした。当時はiOS担当だったため、Androidの実装は当時の担当の方がしてくれた(※1)のですが、最近不定期に機能改善をする際にAndroidのタスク管理機能のメンテナンスに苦心することが多かったので思い切ってアーキテクチャの変更に取り組みました。タスク管理機能の概要WowTalkでは作業内容をタスクとして管理する機能があり、テキスト情報に加えて画像やドキュメントファイルを添付し、タスクの担当者・関係者間で共有できる仕組みです。タスクには期限が設定でき、期限切れ当日には通知が届くようにもなっています。自分はもっぱら個人のタスク管理に使うことが多いこのタスク管理機能は大きく3種類のActivityから構成されています。編集画面は1つのActivityで実装されていたそれぞれ独立したActivityで実装されており、サーバーからのデータ取得リクエスト呼び出しや描画に伴うデータ加工などもそれぞれのActivityで実装されていました。上述したとおり複数の役割を1つのActivityで実装したため、多いものではソースコードの行数が2800行近くにまでなりました。多いと見るかは個人差があるかもしれませんが、個人的にはかなり苦労するレベルです。メンテナンスも忘れた頃にするので、毎回作業時に「これなにしてるんだっけ...」と処理を見返すことが何度もあり、作業効率があまりに悪いということもありました。今回はタスクの詳細・編集画面を改修することにし、下記の2つを実施することにしました。画面ごとにActivityを切り分けるタスクの詳細画面と編集画面は類似したインターフェース及びデータ構造のため、1つのクラスで実装されていましたが、それぞれ表示の仕方が変わるため、モードの切り替え時に逐次ViewのVisibilityを変更していました。これらを個別のActivityに分割することで状態の管理などを気にしなくて済むような実装にしていきます。データとViewの操作をActivityから切り分ける(MVVMアーキテクチャ)合わせてデータ操作とViewの状態管理も切り分けて、それぞれが依存しないようにしていきます。今回はGoogleがAndroidアプリ実装時の推奨アーキテクチャとしているMVVM(※2)を採用することにしました。簡単にMVVMについて書くと、データの取得/送信部分をModel(M)クラスに任せ、ViewModel(VM)はModelからデータを受け取り、View(V)が使いやすい形でデータを提供します(※3)。今回2つの画面のデータ取得ロジックがほぼ同じため、下記の様にModelを共通化した形で変更を加えることにしました。画面ごとにActivityを切り分けた上、MVVMにすることで1クラスあたりのソースコード量が減り、かなり見やすくなりました。合わせて以下の様な効果がありました。・現在の状態を意識する必要がなくなった・クラス内部の変数が減り、各変数への依存関係も減ったためロジックの構築がシンプルになった・表示のための"ビューロジック"と"実際の表示処理"が個々のクラス内で完結しているため、実装時に頭の中で同時に考える負担が減り実装が早くなった1つ目と2つ目は書いている通りで、今の画面が詳細画面なのか編集画面なのかを意識する必要もなく、またそれぞれの状態で利用していた変数を個別のClassで管理する様になったので、条件分岐などの記述が減り1つの関数の行数もだいぶ削減されました。3つ目に関しては実際に経験があるとイメージしやすいのですが、1つのActivity内でデータの取得から表示までの一連の流れを書く場合1バックグランドでデータの取得2受け取ったデータをメインスレッド(Handler)にポストする3メインスレッド内で変数への保存を行いデータの表示処理を行うみたいなことをするわけですが、一連の流れを描く際に1つで今回取り扱うデータとは関係ないデータを取り扱う処理(例えば描画や別の処理のエラーハンドリング関数)をかき分けながらHandlerを探すなんてことがよくあります。これが無くなるだけでもかなり実装時の負担は低減されました。気づいたこと今回実装していて思ったのがViewModelが思ったよりも肥大化したことでした。実装にあたりLiveData(※4)を利用した値の自動更新を採用したのですが、これとビューロジックを一度に実装するとそこそこな分量になりました(1000行程)また通常ModelはSingleton(※5)で実装してDBやサーバーから取得したデータをキャッシュすることを推奨(※6)されているのですが、別のタスクを開いたはずが直前のタスクの情報が表示されてるなんてこともありました。ActivityとModelは依存関係を排除しているとはいえ、用途は想定して実装しないといけませんね。終わりに今回はタスク管理機能のFatActivityをビューロジックの切り分けと整理によって2800行あったソースコードを200~1000行のクラスに分割し、保守性を改善しました。今後はこの画面以外でも同様の問題を抱えている箇所を1つずつ改善していければと思います。当たり障りのない内容でしたが、基本的なことの大切さを実感します。社内ではこういった既存実装が抱える問題を「負の遺産」と呼んでいますが、まだまだ負の遺産はありますので1つずつ返済していきたいと思います。Androidの実装は当時の担当の方がしてくれた決して前任者のソースコードがわかりにくいというわけではないです。MVCと何が違うのかいわゆる昔のModel-View-Controller(MVC)と同じに聞こえるかもしれませんが、個人的に思うControllerとViewModelの大きな違いはまさにViewのModelである点です。画面で表示する際、仕様によって表現を変える必要が出てくる場合があります。UnixTimeで保存し、アプリ側ではこれを「2019-11-29」と表示する場合もあれば「明日」「今日」の様な表現にする場合もあります。これらの表示の上での計算(=ビューロジック)は、MVCにおいてControllerで記述することはせず、Viewで加工することになります。MVVMではこのビューロジックをViewではなくViewModelに担当させることでViewは複雑な処理を記述する必要がなく、表示だけに集中できます。Androidアプリ設計パターン入門https://peaks.cc/books/architecture_patterns我々ワウテック技術開発部はこのような環境で開発をしています。興味を持った方がいらっしゃればいつでもご連絡下さい。12:22大きなActivityは小さく分割したほうがいいお話Tweet関連記事2020-02-05駆け出しエンジニア1年目で学んだ3つのことWeb開発チームのフロントを担当している山本です。最近では技...2020-01-09ペアプログラミングを試してみたどうもこんにちは!web開発チームのしまねです。最近web開発チ...2019-10-041週間で作って社内リリースしたヘルプボットを性能改善した話お久しぶりです。WowTalkのAndroid開発担当している岡野です。...2019-07-241週間でヘルプボット作って社内リリースしたお話こんにちは。WowTalkのAndroid開発担当している岡野です。~Storybook...こんにちは。Web開発チームの島根です。はてなブログProWowTechエンジニアによる開発ブログです。社内チャットツールWowTalkの開発をしています。読者になるSERCHLINKはてなブログブログをはじめる週刊はてなブログはてなブログProNEW駆け出しエンジニア1年目で学んだ3つのことペアプログラミングを試してみた2020年もワウテックをよろしくお願いします大きなActivityは小さく分割したほうがいいお話1週間で作って社内リリースしたヘルプボットを性能改善した話ARCHIVEスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。