2024.10.21
お互い疑心暗鬼になりがちな、経営企画と事業部の壁 組織に「分断」が生まれる要因と打開策
急成長中のレシピ動画サービス『クラシル』を運営する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.11.13
週3日働いて年収2,000万稼ぐ元印刷屋のおじさん 好きなことだけして楽に稼ぐ3つのパターン
2024.11.21
40代〜50代の管理職が「部下を承認する」のに苦戦するわけ 職場での「傷つき」をこじらせた世代に必要なこと
2024.11.20
成果が目立つ「攻めのタイプ」ばかり採用しがちな職場 「優秀な人材」を求める人がスルーしているもの
2024.11.20
「元エースの管理職」が若手営業を育てる時に陥りがちな罠 順調なチーム・苦戦するチームの違いから見る、育成のポイント
2024.11.11
自分の「本質的な才能」が見つかる一番簡単な質問 他者から「すごい」と思われても意外と気づかないのが才能
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.11.18
20名の会社でGoogleの採用を真似するのはもったいない 人手不足の時代における「脱能力主義」のヒント
2024.11.19
がんばっているのに伸び悩む営業・成果を出す営業の違い 『無敗営業』著者が教える、つい陥りがちな「思い込み」の罠
2024.11.13
“退職者が出た時の会社の対応”を従業員は見ている 離職防止策の前に見つめ直したい、部下との向き合い方
2024.11.15
好きなことで起業、赤字を膨らませても引くに引けない理由 倒産リスクが一気に高まる、起業でありがちな失敗