こんにちは。
求人ボックスシステム部メディアチームでエンジニアをしている佐藤です。
普段は金魚のお世話しかしていない私ですが、ここでは求人ボックスのソフトウェアアーキテクチャのご紹介をしたいと思います。
この記事を通して、求人ボックスにおけるソフトウェア開発の考え方や雰囲気が少しでも伝われば幸いです。
開発効率落ちてない…?
2015年にサービス開始し、現在は月間800万ユーザーに利用して頂けるサービスとなった求人ボックスですが、
サービスの成長期に入ってしばらく経った2019年ごろからソフトウェア開発における問題がいくつか見られるようになりました。
- 巨大になったクラス
- あらゆるものと密結合した実装
- 十人十色の命名規則 …etc
エンジニアであれば同様の問題を抱えたプロジェクトに人生で一度は遭遇したことがあるのではないでしょうか。
求人ボックスでもこれらの問題に直面し、この頃から開発効率の低下が懸念されるようになりました。
ということでいくつかの開発指針が定められました。
その中の一つが「求人ボックスのソフトウェアアーキテクチャ」です。
テスタブルで変更しやすい!を実現するソフトウェアアーキテクチャ
求人ボックスのソフトウェアアーキテクチャは、「テスタブルで変更しやすいソフトウェア」が実現する事を目指して考案されています。
これは
正しくテストできる → ビジネスロジックをリファクタできる → コードが綺麗にできる → 変更しやすい
という考え方に基づいているためです。
「最初から完璧なコードを作る」ということは、万人にできることではありません。
そこで、テストを用意しコードの変更コストを小さくすることで、後から少しずつ改善できるようにしていくというところを目指しています。
求人ボックスのソフトウェアアーキテクチャ
求人ボックスのソフトウェアアーキテクチャでは、ソフトウェアを階層に分けて捉えています。
- ドメインモデル層:ビジネスロジックのコードを配置する層
- ユースケース層:機能を表現する層(ビジネスロジックを順に呼び出すイメージ)
- インフラストラクチャ層:ビジネスロジック以外のロジック(DataAccessなど)の詳細がある層
- UI層:入出力データを扱うコードがある層
- ライブラリ層:外部コード(Framework、3rdパーティライブラリ)がある層
最も重要なビジネスロジックのあるドメインモデル層をユースケース層が利用し、最終的にUI層がユーザーに出力を行います。
インフラストラクチャ層やライブラリ層は、必ずインターフェースを介して(ドメインモデル層がそれらに依存しないように)
ドメインモデル層から呼び出されます。
例えば、「求人を検索する」という機能は
- ドメインモデル層:求人をどのような順で並べるか?、どのような求人情報を表示するか?などを決める
- ユースケース層:求人情報の取得、並び替え、整形、…などを順番に呼び出す
- インフラストラクチャ層:検索エンジン、DBなどから求人のデータを取得する
- UI層:HTTPリクエストデータを受取る&生成する、HTMLをレンダリングする
- ライブラリ層:HTTPリクエストを行うクライアント、DBとのやりとりを行うライブラリ
それぞれがこのような役割を担い、それらが組み合わさる事で機能が実現されます。
また、このようにそれぞれの層の役割をはっきりさせ分離する事で、層の間の依存関係を断ち切ることもしやすくなります。
そして、依存関係が少なくそれぞれがシンプルな処理の集まりであれば、それぞれのテスト作成における余計なコストも少なくなります。
例えば、以前の求人ボックスにはユースケース層がなく、様々な種類の処理がUI層で行われていました。
(Webフレームワーク上からビジネスロジックを呼び出したり、DBに問い合わせをおこなったり…)
そのため、テスト作成にはWebフレームワークやDBを用意することが必要で、
そのコストは大きく結果的に十分なテストはできていない状態でした。
しかし、このアークテクチャに沿った開発をしたことで、テストするのに必要なのはUseCaseクラスだけになり、
インフラストラクチャ層への依存が切り離された事で「テストの時だけモックに差し替える」といったことも可能になりました。
結果として、テストを用意するコストは小さくなり、テスト自体もよりシンプルになりました。
導入してどうだった…?
テストを"書ける"ようになった
繰り返しになりますが、このアーキテクチャは「テスタブルで変更しやすいソフトウェア」を実現するために考案されました。
そのため、このアーキテクチャに沿って作られた機能は、テストを用意することが比較的容易になりました。
テストが"書けない"状態から"書ける"状態になったことは、このアーキテクチャを導入した最も大きな成果だと思います。
テストを"書きたい"にはまだ到達していない…
一方で、「思ったよりテストが増えない」という課題も見えてきています。
つまり、現状は「テストは"書ける"けど"書きたい"という状態になっていない」という感じです。
日々機能の実現とリリースに追われる中で、「テストを作る」というタスクは優先度が低くみられがち、というのが正直なところです。
この辺りはソフトウェアアーキテクチャだけなく、開発フローの改善(自然とテスト作成が必要となるフローにする) や
テスト作成スキルの向上などの別の取り込みも重要になってくるのではないかと考えています。
「開発を進めていたら自然とテストも作ってたし、テスト作成スキルもついてハッピー♪」というような
開発フローが実現できないか模索していければと思います。
おわりに
本記事作成にあたり、求人ボックスシステム部プロダクトチーム 松浦さんにご助言を賜りました。
ここに感謝いたします。
カカクコムでは共にサービスをつくる仲間を募集しています
カカクコムのエンジニアリングにご興味のある方は、是非こちらをご覧ください!