💡

組織のパターンを参考にモジュラーモノリスの設計を考える

に公開

最近、Railsでモジュラーモノリスの設計を考えている中で、個人的に面白い気づきがありました。

私はふだん、Packwerkを使ってドメインごとのコード分割を行うことがあります。たとえば「注文」や「ユーザ管理」など、機能単位でパッケージを切って責務を明確にする、いわゆるドメイン駆動っぽい分割です。

同時に、「Layered Design for Ruby on Rails」で紹介されているような、技術的なレイヤー構造も参考にしています。フォームやポリシー、クエリやフィルターといった明確な抽象化レイヤーから成る構成は、処理の流れが見通しやすく、個人的にも心地よく感じます。

ただ、この2つのアプローチを同時に取り入れようとすると、どうしても混乱が生じてしまいます。
機能単位でコードを分けながら、その中で技術レイヤーも意識するとなると、「どちらを優先すべきか」で迷う場面が出てくるのです。現状では、機能ごとのパッケージの中に技術レイヤーを配置する構成を採用していますが、いまだにモヤモヤする瞬間があります。

マトリックス型組織との共通点

そんなときにふと思い出したのが「マトリックス型組織」の構造でした。

プロダクト単位のチームに、エンジニア・デザイナー・QAなどの職能が横断的に所属している、つまり「機能」と「職能」の2軸で構成される組織構造で、私が所属する組織もこのような構造を持ちます。これはドメインと技術レイヤーの両立を目指すモジュラーモノリス設計とよく似ているなと感じます。

「機能」と「職能」は、どちらもそれぞれ理にかなっている一方で、「どこに線を引くか」が難しく、責任や意思決定の範囲があいまいになることもあります。構造としては非常に実践的であると思いますが、バランスを取るのが簡単ではないと感じるときがあります。

コンウェイの法則からの発想

そこで思い出したのが「コンウェイの法則」です。
「組織構造は、そのままソフトウェアに反映される」という有名な考え方です。そして「逆コンウェイ戦略」では、「望ましいアーキテクチャを実現するために、組織構造のほうを意図的に設計しよう」と言われています。

そう考えると、モジュラーモノリスのパッケージ設計には組織構造がヒントになるのではないかと思えてきました。

チームトポロジーとの対応

私にとって組織構造で真っ先に思い浮かぶのが「チームトポロジー」です。
このフレームワークでは、チームを4つのタイプに分類し、それぞれの役割や関係性を整理しています。そしてこれが、モジュラーモノリスのパッケージ設計にそのまま応用できるのではと思いました。

チームの型 特徴 モジュラーモノリスでの対応例
ストリームアラインドチーム ユーザに価値を届ける機能を担当 機能単位のパッケージ(注文、ユーザなど)
コンプリケイテッド・サブシステムチーム 高度で専門的な技術を扱う アルゴリズム系、レコメンド、料金計算など
プラットフォームチーム 共通の基盤やツールを提供 認証、通知、ロギングなどの共通パッケージ
イネーブリングチーム 他チームの支援や能力開発を担う 開発ツール(packwerk や packs-rails、リンター、ドキュメント生成ツール、型システムなど)のような支援要素

また、チームトポロジーでは、チームのタイプだけでなく「どう関わり合うか」という視点でも整理されています。これは「インタラクションモード」と呼ばれていて、大きく3つの種類があります。

この考え方をモジュラーモノリスの中でのパッケージの関係に当てはめてみると、こちらもまたヒントになりそうです。

  1. コラボレーションモード
    チーム同士が一時的に深く連携して、一緒に課題に取り組むときの関係です。モジュラーモノリスの文脈では、パッケージ間の責務の切り分けがまだはっきりしていない状態、もしくは依存関係に課題がある状態に近いと思います。
    たとえば、Packwerkの警告にあるような「他のパッケージのプライベートコードを触っている」ケース。これはまさに、まだ責務があいまいで、チーム同士が密に連携しながら切り分けを進めていく必要がある時期です。

  2. X as a Serviceモード
    一方のチームが、他のチームのためにサービスや機能を安定して提供するモードです。モジュラーモノリスの中では、すでに責務が整理されたパッケージが、他のパッケージに対して明確なインターフェースを提供しているような状態に見えてきます。
    たとえば「認証」や「通知」などの基盤系のパッケージは、他のパッケージからAPIのように使われることが多く、このモードに近いと感じます。

  3. ファシリテーションモード
    これは直接的な機能提供ではなく、他のチームの課題解決を助けるような関わり方です。コードで言えば、リントルールやガイドラインの整備、あるいはテストツールの提供、ドキュメントの充実などが該当するかもしれません。
    モジュラーモノリスでは、パッケージの形でこの活動が見えるわけではないけれど、開発全体のスムーズさを支えるうえで欠かせない部分です。ファシリテーション的な貢献が、開発者の間で自然に知識が伝わっていく基盤になっていると感じます。

最後に

アーキテクチャ設計というと、どうしてもコードや技術の話が中心になりがちです。私もこれまで、ドメイン駆動設計などの技術書を中心に、設計のヒントを探してきました。

しかし、組織構造やチームのあり方といった、技術とは異なる分野にも多くのヒントがあると感じています。そういった視点から考えることで、迷いがちな設計の判断に、新たな視座が得られるかもしれません。

モジュラーモノリスの良い設計を探るために、組織デザインについてもインプットしていくと、また新たな発見があって面白そうです。

YAMAP テックブログ

Discussion