2024.12.19
システムの穴を運用でカバーしようとしてミス多発… バグが大量発生、決算が合わない状態から業務効率化を実現するまで
急成長中のレシピ動画サービス『クラシル』を運営するdelyが、 これまでのグロース戦略、エンジニアリング方針、ユーザー調査手法等についてお話しします!(全6記事)
リンクをコピー
記事をブックマーク
梅森翔氏(以下、梅森):こんばんは。Androidエンジニアをやっています。今テックリードと紹介いただきましたが、テックリードみたいなこともやりつつ、Androidエンジニアをやっています。
今日はテックリードっぽい話はしないんですが、Androidの開発についての話をしたいと思います。タイトルとしては「継続的なアーキテクチャ改善の理想と現実」というタイトルで発表します。
自分がdelyに入って1年と2ヶ月経ちました。入社時はテレビCMをやって一気にアプリがグロースした時期でした。今年のDroidKaigiで登壇したりしています。
今日発表する内容としては、今のdelyのAndroidのアプリケーションがどんなアーキテクチャであるかということと、自分が入った頃はどんな感じだったか。そしてそれをどうやって改善したかという話をしたいと思います。
2018年7月現在のAndroidアプリケーションのアーキテクチャはこんな感じになっています。Activity、Fragmentがあって、Viewの層があって、あとで細かく説明はしますが、Applicationがあって、Data層、Infra層があって、4層のレイヤードアーキテクチャになっています。
サービスもあるのでServiceが左のほうにありますが、Serviceがあり、それらがData層、Infra層に紐付いているという実装をしています。現在は一般的なアーキテクチャなのかなと思っていますが、こんな感じでやっています。
理想はこんな感じです。現実としては若干アーキテクチャのルールを守っていないコードがあったりするのですが、こんな感じでやっています。
先ほどざっくり説明したのですが、4層のアーキテクチャでやっています。View層、Application層、Data層、Infra層、Service。+1というのは、Serviceは厳密にいうとActivityやFragmentのライフサイクルとは違うものなので分けています。
ViewはMVVMを採用しています。だいぶ前にAndroid ArchitectureのComponentsが出てきて、ViewModelというのが出てきたんですけど、みなさんこれはどうしていますか? けっこう名前に困ってます?
Android Data Bindingを活用して実装しています。ViewModelでイベントハンドリングとプロパティバインディングをやっているというスタンダードな感じですね。
Application層はViewModelのイベントを受け取って、Data層を操作し、そのデータをViewModelに返す。ここはまだ実装中、未完成なんですけど。
Data層があります。右に書いてあるのは、クラス名に末尾にこんなことをつけたりする、という決まりになっていたりします。ローカルの永続化周りの操作やWeb APIの呼び出し、メモリ上の一時的なデータの取り扱いなどを行っているような層ですね。
Infra層、その他すべて。今話したことに関わらないところは全部ここに押し込めるみたいな感じで今はやっています。DI周りだけはパッケージを分けていますが、それ以外は一緒くたになっている感じですね。
最後にServiceですが、これはいわゆるAndroidのServiceなので、Activityのバックグラウンドで起動したりするものです。直接Data層にアクセスしてて、ほぼApplication層のようなものだから、Data層にアクセスしてるみたいな感じでやっています。ここは実装しながら悩んでいる感じですね。
いいところとしては、それぞれの層の役割が明確になっています。最悪Infra層に閉じ込めておけばなんとかなるだろう、みたいな感じで実装できるのがいいところです。複雑な機能もRepositoryとApplicationにうまく分割すれば整理しやすいのがいいところです。
現状のよくないところとしては、大規模にパッケージをリファクタリングしたところでヒストリが途切れているところがあったりして、そこはよくなかったり。先ほど見せたとおり、完全に設計どおりのつくりにはなっていないので、そういうところはよくないですね。
まだ移行しきれていない実装もところどころ残っていたりします。でも、悪くはないレベルになってきています。
自分が入った頃のアーキテクチャはこんな感じでした。登場人物がとても少なくてシンプルですね。入った時に「このままだとまずそうだな」と思いました。とくに設計思想もなく、いろいろな人の手を渡ってきた感じのするコードでした。
その頃、ユーザー数はグロースしていたんですが、開発チームはスケールしなそうだと思ったので、その当時もう1人いたAndroidエンジニアに協力してもらってアーキテクチャ改善に取り組むことにしました。
アーキテクチャといえば、みなさんご存じだと思いますが、コンウェイの法則というものがあります。「システムを設計する組織は、その構造をそっくり真似た構造の設計を生み出してしまう」。つまり、システムのアーキテクチャは組織構造に従うという法則ですね。
逆に言えば、悪いアーキテクチャは組織構造を悪くするし、良いアーキテクチャは組織構造を良くする。これは逆コンウェイの法則と言ったりします。
というわけで、サービスと一緒に成長するためにアーキテクチャを改善しました。
まずやってみたことです。とりあえずActivity、Fragmentがここで一緒くたになっていたので、Viewを分離したいと。幸いなことに当時Data Bindingを使っていたので、Butter Knifeと同じような使い方をしてましたが、MVVMを導入しました。
ちょうどその頃まったく新しい機能の実装を任されたので、サンプル的に画面をいくつか作ってもう1人のAndroid開発者に共有をし、小さく始めました。
たしか、6〜7月ぐらいに第1段階が完了したと思います。9割ぐらいの画面を、実際にView層を作ってMVVM化することができました。
次に、View・Infra層を整理しました。
同じ画面を構成しているViewModel、あるいはActivity、Fragment。この画面は動画の一覧の画面なんですが、実際にはその画面を構成しているコンポーネントはもっといろいろあります。ListだったのでAdapterがあったり。そういったものを一緒くたに同じパッケージ構造に置いたり。
そして、9割ぐらいのAndroid SDK API呼び出しをInfra層に切り離しました。
その結果、若干整ってきました。でも、まだ層としては少ないので、ViewModelに複雑な処理が残っているという感じです。
次にData層を切り離しました。APIへの通信やローカルのSharedPreferenceの書き込み、呼び出しなどを〇〇Repositoryに切り出しました。ローカルとリモートを切り分けて、そこでざっくり分けたような感じでやりました。
もともとUseCaseという名前でAPIの通信が切り離されていたので、それのリネームがメインでしたが、いろいろと整理しました。
そういうことをやった結果、View層からIO関係の処理が消えました。ただ、新しく作ったData層に今度は複雑な処理が集中してきました。
というわけで、Application層を切り離すことにしました。Data層で扱っている複雑めな処理をApplication層に移動。Serviceも、これとは別なんですけど、Data層を参照するように切り替えました。
12月ごろにほぼ現在に近いかたちになって、今もすこしずつ、構造はできたので改善しているという感じです。
ほかにもいろいろやったんですが。Dagger2のライフスコープを切り分けたり、イベントハンドリング用のイベントバス作って導入したり、RxJavaを導入したり、いろいろやりました。
1年ぐらいやってみた感じですね。これがコントリビューションの結果なんですが、25万行足して17万行減らしています。
感想としては、なかなかつらかったですね。最初はあまりいいコードではなかったですし、今でも完全によくできてはないし、最初からきれいだったらもちろんよかったと思います。
でも、サービスの成長段階によって必要となるアーキテクチャは違うと思います。価値がすばやく届けられるのが大事だし、グロースする前にオーバーキルのアーキテクチャはいらない。なので、人が増えていくタイミングやアプリが複雑化するタイミングで変えちゃえばいいじゃないかと思います。
それはけっこうつらいんですが、そのときに苦しめばいいし、今日説明したようにちょっとずつレイヤーを増やして移行することもできます。
というわけで、クラシルはこれからも成長していくので、サービスの成長と一緒に成長するプロダクト、そしてアーキテクチャを育てるAndroidエンジニアを募集しています。ありがとうございました。
(会場拍手)
2024.12.20
日本の約10倍がん患者が殺到し、病院はキャパオーバー ジャパンハートが描く医療の未来と、カンボジアに新病院を作る理由
2024.12.19
12万通りの「資格の組み合わせ」の中で厳選された60の項目 532の資格を持つ林雄次氏の新刊『資格のかけ算』の見所
2024.12.16
32歳で成績最下位から1年でトップ営業になれた理由 売るテクニックよりも大事な「あり方」
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
PR | 2024.12.20
モンスター化したExcelが、ある日突然崩壊 昭和のガス工事会社を生まれ変わらせた、起死回生のノーコード活用術
2024.12.12
会議で発言しやすくなる「心理的安全性」を高めるには ファシリテーションがうまい人の3つの条件
2024.12.18
「社長以外みんな儲かる給与設計」にした理由 経営者たちが語る、優秀な人材集め・会社を発展させるためのヒント
2024.12.17
面接で「後輩を指導できなさそう」と思われる人の伝え方 歳を重ねるほど重視される経験の「ノウハウ化」
2024.12.13
ファシリテーターは「しゃべらないほうがいい」理由 入山章栄氏が語る、心理的安全性の高い場を作るポイント
2024.12.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
Climbers Startup JAPAN EXPO 2024 - 秋 -
2024.11.20 - 2024.11.21
『主体的なキャリア形成』を考える~資格のかけ算について〜
2024.12.07 - 2024.12.07
Startup CTO of the year 2024
2024.11.19 - 2024.11.19
社員の力を引き出す経営戦略〜ひとり一人が自ら成長する組織づくり〜
2024.11.20 - 2024.11.20
「確率思考」で未来を見通す 事業を成功に導く意思決定 ~エビデンス・ベースド・マーケティング思考の調査分析で事業に有効な予測手法とは~
2024.11.05 - 2024.11.05