2024.12.19
システムの穴を運用でカバーしようとしてミス多発… バグが大量発生、決算が合わない状態から業務効率化を実現するまで
提供:LINE株式会社
リンクをコピー
記事をブックマーク
大石将邦氏:では、次のトピックに移りたいと思います。次はプロジェクトのマルチモジュール化についてです。そもそも、なぜマルチモジュール化が必要なんでしょうか?
プロジェクトをモジュールに分割することによって、ソースコードが機能ごとに分割されます。そうすると変更による影響範囲が把握しやすくなります。そうすることによって、例えば拡張性を高めることができるわけですね。拡張性というのは数値化するのが難しい指標かもしれませんが、一方でもっとわかりやすい指標としてはビルドスピードの向上というのが挙げられます。
LINE Androidアプリは、テストコードを抜いたプロダクションのコードだけでも160万行を超えています。これだけ大きいとビルドに掛かる時間はかなり長くなるので、モジュール化することによってビルド時間を短縮させることは我々のチーム内でも非常に重要なトピックの1つです。
さらに、比較的新しい機能であるDynamic Feature Moduleとon-demand deliveryという機能を利用することによって、アプリの機能をユーザの端末に分割してダウンロードさせることができるようになります。そうするとインストール時のアプリサイズを大きく削減することができるということにもなります。
ということで、モジュール化は基本的に良いことなんですけど、実際にやろうとすると依存性の問題とかいろいろありまして実際にやるのは意外と難しいです。そこで、我々がどのような方針でモジュール化を行っているか、その手法についてお話しようと思います。
ではまず、図で説明しましょう。モノリシックな1つの大きなプロジェクトがあり、そのクラスの関係がこの図のようになっているとします。このうち右下のFoo featureと書かれた部分をモジュールとして切り出すことを考えましょう。
まず、機能の入り口となるクラスをFacadeクラスとして抽出します。これはデザインパターンの1つであるFacadeパターンのことです。具体的な例を挙げると、例えばLINEのようなメッセージアプリにおいて自撮りカメラの部分を独立した機能として切り出す場合、そのカメラ機能を立ち上げるメソッドをFacadeクラスに用意する感じですね。
このように、ある機能を呼び出すメソッドをFacadeクラスに定義していきます。そして、その機能の外からその機能を呼び出す場合、必ずそのFacadeクラスに対して呼び出しを行うようにします。
先ほどの図に戻ると、Foo featureのコードは合計3ヶ所から呼び出されています。なのでこの3つの呼び出しをFacadeクラスを経由するように変えます。このとき、Foo featureから「外向き」の呼び出しについては今はとくに触る必要はありません。あくまでfeatureへの呼び出しをFacadeクラスとして切り出すことが重要です。
次に、先ほどのFacadeクラスをインターフェースとインプリメンテーションクラスに分割します。
そうすると、Foo featureの「外」のクラスはFooFacadeのインターフェースだけを知っていればよい状態になります。
ここまでくれば、Foo featureをモジュールとして分割することができます。app moduleはFooFacadeインターフェースだけを見ていてFoo module本体には依存しておらず、一方でFoo module本体はapp moduleに依存している状態になります。「これでモジュール化が完了です!」と言いたいところなんですが、1つ問題が残っています。
それは実際のコードでFacadeのメソッドを呼び出すときに、そのインスタンスをどうやって手に入れるのかという問題です。ここで勘の良い方は当然「DI使ったらどう?」と思っているでしょう。
ここでもう一度お尋ねします。今、Android開発者の方でDagger2を使っているという方は手を挙げていただけますか?
(会場挙手)
やっぱり多いですね。ほぼデファクトのDagger2、もしくは最近流行りのKoinなど、Android開発で使われるDIツールはいろいろありますが、マルチモジュールプロジェクトにおける今のような問題を解決するのはとても面倒くさかったりするんです。なので、我々はこの問題を解決するのに独自のライブラリを作ることにしました。
この独自ライブラリを使うと、マルチモジュールプロジェクトの依存関係が簡単に解決できます。
まず、Facadeインターフェースの方にcompanion objectとして数行のコードを書き加えます。一方で、インプリメンテーションクラスの方にはAutoServiceというアノテーションを付けます。たったこれだけで先ほどの依存関係の問題は解決します。
実際に使う場面では、このコードのように”by component(FooFacade)”と書くだけです。これでFooFacadeImplのインスタンスがどこからでも簡単に取得することができるようになります。
これで本当にFoo featureのモジュール化が完了です。このようなことをプロジェクト全体でやっていきます。
引き続き、この図の右上の部分と左下の部分をそれぞれモジュール化してみましょう。やることは同じです。それぞれについてFacadeクラスを作り、それをインターフェースとインプリメンテーションに分割します。すると最終的にこうなります。
もはやapp moduleは、それぞれのFacadeインターフェースにしかアクセスしません。また、各feature moduleがお互いを呼び出す場合も、相手のFacadeインターフェースだけを知っていて、それに対してアクセスしています。こうやって分割していくことによって、大きなモノリシックなプロジェクトをfeature moduleに分割できるのです。
実際に我々のLINE Androidプロジェクトも、このような方針で現在もモジュール化を行っています。
モジュール化の話についてまとめましょう。まず、ある機能の入り口をFacadeとして抽出し、他の機能からはそのFacadeに対してのみアクセスするようにします。そして、そのFacadeをインターフェースとインプリメンテーションの2つに分割します。最後に、我々の作ったLichという名前のライブラリによって、Facadeの依存関係を解決して完了です。
ここまで何度か話題にしましたが、我々LINE Androidプロジェクトの開発において、いくつかの基礎的なライブラリを作ってきました。これらのライブラリをまとめて、Lichという名前のオープンソースプロダクトとしてGitHub上に公開しています。
今日紹介しましたCoroutines、およびマルチモジュールの依存性解決に関するものの他にもViewModelやokhttpなどに関するライブラリたちをまとめてLichという名前でこのURLにて公開しています。ぜひ、このライブラリをチェックアウトして、みなさんの開発にも役立てていただけると幸いです。
そして気に入っていただけたら、GitHubのスターを付けていただけるとありがたいです。
最後にこのライブラリを紹介させていただいたところで、私の発表は以上となります。ありがとうございました。
(会場拍手)
LINE株式会社
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