モジュールの分割点

アーキテクチャの問題とは、システムをどこで分割 (decomposition) するかという問題と言い換えてよいでしょう。分割するのは、魚を捌くのと同じようなもので、包丁を入れるべき場所というのがあります。

分割するというからには、切り分けるサイズがありますが、今回は分割の単位の議論はしません。なぜかといいますと、ちゃんとつくれば、システムの部品は入れ子構造になっているはずです。再帰的に作られているという言い方もできます。つまり、システムを切り分けて出てきたものは、やはり同じやり方で切り分けることができます。マトリョーシカというか、フラクタル的といいますか、問題を切り分ければ同じものが出てくるはずです。明らかに正しいことが分かるサイズが最小単位で、そこに至るまで分割を繰り返されたものが、ちゃんとした仕事でしょう。

問題をバラすときにタテに切るかヨコに切るか、そしてその切り目はどこかというのは、分割のサイズに依らず決まっているように思います。まだ全てを発見したわけではないし、重複もあるかもしれないということを断った上で、以下を挙げます。

データ構造

特にクラスベースのオブジェクト指向プログラミングではデータ構造でモジュールを分割するのが基本でしょう。データを統べることが機能であり責務であるというところから、データ構造とデータの操作を切り出してまとめたのがクラスです。人間が計算機にさせたいことは、データの変換と記録だけなので、データから考える方が簡単です。人間の興味とシステムのアーキテクチャが一致していたら、扱いやすいものができるそうなことは想像がつくでしょう。

トランザクション

システムのアーキテクチャは人の興味に一致していた方が便利である――というのは経験則であります。データ構造からたどる方が一般にやりやすいと思いますが、システムにやらせたいこともシステムの切り目です。WEB システムに API が複数生えていたら、当然 API ごとにモジュールを切り分けますよね?やらせたいことは、トランザクション/手続きといった方が分かりやすいかもしれませんが、それらごとにモジュールは分割されます。クラスの中もメソッドが分かれております。これもデータ構造に対してやらせたいことごとに分割されているはずです。

共通機能

同じシステムは一つとないとはいっても、だいたいどんなシステムも似たようなものでして、全く同じ機能がいることが多々あります。そういうものは共有できるように別モジュールに切り出した方が便利です。ライブラリとかフレームワークとか呼ばれたりします。ただし、意味もなく再利用を志向するのは避けるべきです。そういうのが再利用されることはまずありません。

レイヤードアーキテクチャは共通機能で分割する手法の一種です。分解して抽象度を落としていくと、同じものが必要になります。自然界だって要素に分解していくと、原子・素粒子と全てが同じになります。同じものはみんなで共有して使いまわした方が便利です。

組織

コンウェイの法則で知られるものです。組織が異なったらモジュールも分かれます。人が異なってもモジュールは分かれます。組織が巨大化しているのに、モノリシックなアーキテクチャを維持するのは無理です。組織を編成するひとは、アーキテクチャを知って仕事をしないと、組織は上手く回らないでしょう。

開発の時系列

後から機能を加えるときは、取ってつけたように追加せざるをえません。組織でモジュールが分かれるように、たとえ同じ人がやっていたとしてもプロジェクトの単位でモジュールが分かれるでしょう。開発プロジェクトは何かしらの論理的な単位で切られるものなので、そこでモジュールが分かれるのは不自然ではないでしょう。むしろ、既存のモジュールに変な条件文を加えるほうが、不自然な改修だと思います。