この記事は株式会社カオナビ Advent Calendar 2024の5日目の記事です。
はじめに
ソフトウェア開発は、不確実性がとても高いです。
- 問題を解決するために提案されたプロダクトが、実際にその課題を適切に解決できるかどうかは分からない
- 実際に問題解決がされたところで、利益となるかは分からない
- プロダクトを開発するにあたり、期間などのリソースが正確に予測できない
こうした問題に対処するため、私たちは短期間での仮説検証を繰り返しながら、常にプロダクトを改善し続ける姿勢が必要になります。
この記事では、開発チームの立場から貢献するために「ソフトウェアは捨てやすく作りませんか?」という話をしたいと思います。
どうして捨てやすく作るのがいいのか
仮説検証を繰り返しながらソフトウェアを開発していると、たびたび「必要だと思って作ったけど、やっぱり要らなかった」ものが出てきます。
次の図にあるようなスタートアップ・フィット・ジャーニーで言うところのPMF(Product Market Fit)前のプロダクトでは、実際のユーザーのニーズが掴みきれていないため、特に実験的に作った不要な機能が出てきやすくなります。
不要なコードを消した方がよさそうなことは、なんとなく理解いただけるかと思います。
しかし、次のような理由からコードを消すという作業は後回しにされがちです。
- ビジネス的には、別に消さなくてもユーザーから見た振る舞いは変わらない
- エンジニアリング的には、消したら何かが動作しなくなる可能性があってリスクが高い
そうした積み上げの結果、コードベースに対する認知負荷が上がるなどして、コード品質が下がり、ビジネスにも影響を与えてしまうことになります。
そのため、できるだけコストをかけずに不要なコードを消せるよう、設計していく必要があると考えています。
捨てやすく作るために取り組んでいること
ソフトウェアを捨てやすく作るのがよいことは分かりましたが、実際何をしたらいいのでしょうか?
チームで同じ方向を向く
まずは 「捨てやすく作る」 という方針を開発チーム全員で認識合わせしましょう。
チームで同じ方向を向くことで、後々の開発を進めやすくできます。
私たちのチームでは、インセプションデッキの中で、次のようなことを掲げました。
- 捨てる勇気を持つ
- 10分以内に機能が消せるように作る
このように言語化して共有することで、普段の開発中にも「捨てやすく作るため、〇〇な方向性にしましょう」といった会話がされるようになり、開発が進めやすくなったと思います。
ディレクトリを機能単位で切る
実際に捨てやすく作るには、どうしたらいいのでしょうか?
私たちは、捨てやすく設計されたコードベースにするため、ディレクトリ構成をレイヤーに基づいた構成(Package by Layer)ではなく、フィーチャーに基づいた構成(Package by Feature)を採用しています。
具体的にイメージできるよう、Laravel で書かれているコードベースのディレクトリ構成での例を見てみましょう。(一部抜粋)
/app
├─ Http
│ ├─ Feature1
│ ├─ Feature2
│ └─ Feature3
├─ Models
│ ├─ Feature1
│ ├─ Feature2
│ └─ Feature3
├─ Services
│ ├─ Feature1
│ ├─ Feature2
│ └─ Feature3
...
/app
├─ Feature1
│ ├─ Http
│ ├─ Models
│ └─ Services
├─ Feature2
│ ├─ Http
│ ├─ Models
│ └─ Services
├─ Feature3
│ ├─ Http
│ ├─ Models
│ └─ Services
...
このように Package by Feature は機能単位でファイルがまとまっています。これによって、特定の機能についてのコードを探しやすくなります。
また、同時に機能を消す時には該当のディレクトリ配下をすべて削除するだけなので、特定の機能をまとめて消しやすくなります。
その際、依存関係に注意して、高凝集 で 低結合 を実現できるようにしましょう。
せっかくディレクトリを分けても、結合度が高いとコードを消す際の依存関係が分かりにくくなってしまいます。
しかし、実際にやってみると開発規模が大きくなるにつれて、仮説検証したい細かい機能単位でディレクトリを切るのが辛くなってくるはずです。
そのため、私たちは次のようにディレクトリの階層構造を作ることで、仮説検証したい機能が多くなっても管理しやすくなるようにしています。
/app
├─ Feature1
│ ├─ Feature1-1
│ │ ├─ Http
│ │ ├─ Models
│ │ └─ Services
│ ├─ Feature1-2
│ │ ├─ Http
│ │ ├─ Models
│ │ └─ Services
│ └─ Feature1-3
│ ├─ Http
│ ├─ Models
│ └─ Services
├─ Feature2
...
こうすることで、仮説検証したい細かい機能単位でディレクトリを切っても、管理しやすくなります。
まとめ
- 短期間で仮説検証しながら開発するために、ソフトウェアは捨てやすく作る
- 捨てやすく作るために、機能単位でディレクトリを切る
このようにソフトウェア開発する上で捨てやすく作ることは、プロダクトの競争優位性を保つためにもオススメです。ぜひ取り入れてみてください。
参考資料
- スタートアップ・フィット・ジャーニー 今どの段階にいて、何に取り組むべきかのガイド - FoundX
- コード品質はやはりビジネスに影響を与える - mtx2s’s blog
- Package by Layer vs Package by Feature - Sahibinden Technology
- ソフトウェア開発って なにか?を学ぶ勉強会 - Yasunobu Kawaguchi
- カオナビにおける マイクロサービスの取組と今後の展開 - Ryo Tomidokoro