Edited at

プロジェクト内パッケージの依存関係をCIでテストする

PicApp アドベントカレンダー10日目です。

チーム開発をしている際に、こういうことは起きていないでしょうか。


  1. 新しく入ったメンバーにアーキテクチャや設計方針を説明する

  2. 実際にコードを書いて Pull Request を投げてもらう

  3. 意図しないパッケージにコードを書かれ、パッケージ間の依存関係がぐちゃぐちゃになっている

  4. コードレビュー時に「このパッケージはこういう意図で分割しているのだからこのパッケージに依存させないでください」と指摘(そしてレビュワーは依存関係のチェックのために、特に import 文を目を皿にしてチェックする)

あるいは、プロジェクトを引き継いだりしたときも同じような状況が起こりえます。前任者の設計意図が後任者に伝わらずに、自身の価値観で再設計を行って、全体の設計が壊れてしまったりします。

こういったことが起きること自体は極めて自然なことなので、悪いことではありません。しかし、それが引き起こした結果を許容して構築されたシステムが 「悪い設計」 に陥ってしまっているのは間違いないでしょう。多くの開発者はそうならないように、日々血眼になってコードレビューしたり、できるだけ効率よく設計意図を共有するためにペアプログラミングをしたりしているはずです。


この記事で伝えたいこと

設計とは問題を解決するために適切な分割構造を選択することであり 1 、その分割構造の一端はパッケージのツリー構造に現れます。

逆に言えば、パッケージツリー構造(依存関係)を設計意図通りに保ちつづけることはプロジェクト全体の設計方針を統一することにつながります。

そのため、これは目視で逐一チェックせず CI でテストすべきなのです。

そして、golang でこれを行うツールとして作ったものが impas です。

https://github.com/tomoemon/impas


具体例

具体例を上げましょう。多くのプロジェクトは何らかのレイヤードアーキテクチャを採用しているはずです。下図はいわゆる DDD 2 の簡単な例ですが、UI 層はアプリケーション層やドメイン層、インフラ層に依存することができる一方で、ドメイン層やインフラ層は UI 層には依存させてはいけません。依存関係の方向を制限することで、特定の層の責任を限定し、わかりやすく、かつ拡張しやすい構造を保つことができます。

project_structure

impas がやることはこの依存関係の方向が期待通りになっているか検査することです。

インフラ層(infra パッケージ)の中にあるコードが import していいパッケージをあらかじめ設定ファイルに記載(ホワイトリスト方式)しておくことで、インフラ層から UI 層(ui パッケージ)のコードを import していたら NG を返すことができます。

impas を CI に組み込むことで、自動的にテストに失敗させることができるため、プロジェクト初心者であっても、その import が(少なくともこのプロジェクトの)設計上ダメであることがすぐにわかります。

パッケージの依存関係というのは、プロジェクトを深く知っている人であれば当たり前に認識している、暗黙知になりがちなことで、新しく入ったメンバー全員にすべてを共有することが難しい知識です。CI に組み込んで誰でも明白にわかる状態にしておくことが、チーム開発をスムーズに進める一つの方法になるのではないかと思います。





  1. 開発現場で役立たせるための設計原則とパターン https://nekogata.hatenablog.com/entry/2018/09/10/163206 



  2. DDD 自体に習熟しているわけではないので、間違いがあれば指摘ください