インターフェイス分離原則とコンウェイ法則

# 前提知見
## インターフェイス分離原則
これはめちゃくちゃシンプルに言うと、インターフェイスにあまりにも多くの処理を持たせるなということ。結果的に【１つの具体に対して、複数の目的が存在しうる】。
その際の目的は、意味のある単位で切り分けなさいてことなんだけども、
それを考える際に個人的には以下の観点で必ず瞬時に視るようにしている。

・そのインターフェイスを使う側から見て、使わない処理があるかないか。
・インターフェイス名前を隠してみて、公開されている処理の集合であるインターフェイスに対して、曖昧な名前しか付けられないのか？　それとも唯一１つの名前を迷わずにつけられるか？

１つ目は外から見た時にインターフェイスに余計な使わない処理がないかをチェックてことで、
２つ目は内から見て処理のまとまりに対して１つだけの名前を付けられるか？
というある意味、単一責任原則にちょっと似ていると思っている。

ポイントは、この【内からと外からの両方でチェックする】てところ。

# 背景
上記のインターフェイス分離原則をビジネスにも生かせる例として、
去年からずっと意識してデザインしているけど、
なかなかその良さが人に伝わらないので、あえて記事に残そうと思ったというのがいきさつである。
そこで以下では、あるシーンを例としてどのようにビジネスをデザインするか？
そこにインターフェイス分離原則をどう有効活用できるのか？
をわたしの数少ない検証実験をもとに行きついた仮説を記載する。

# 想定シーン
ある事業Aで使われている安定した枯れたコンポーネントがあったとしよう。
そして、新たに新規で立ち上げた事業Bのビジネスモデルを構築している途中で、
先程のコンポーネントを再利用できることが判明した。
このコンポーネントがまだ安定していないのなら、変更リスクを考慮しなくてはいけないが、枯れたコンポーネントであり、
品質も十分保証されているため、再利用すると意思決定されているシーンを想定する。

その際にイメージ図として下図のような状態である。
最上位の紫ブロックとして、各事業の最上位の目的。
次に事業Aのそのコンポーネントに求める果たしたい目的、
事業Bのそのコンポーネントに求める果たしたい目的をブルーのブロックで表している。
それらを共に実現したものとして、今回再利用したいコンポーネントがいる。
<img width="400" alt="再利用とインターフェイス分離原則.png (22.0 kB)" src="https://img.esa.io/uploads/production/attachments/5827/2024/01/22/135213/bbffe5fb-e9b5-4782-a5f3-5add3cdfa682.png">

勿論この際に、事業AではコンポーネントのVer1.0を
事業BではコンポーネントのVer1.3を使いたいんだよねって時には、
図のような関係性にはなり得ない。
その際には、是非とも、【リリース再利用等価原則】を思い出していただきたい。
すでにその記事は書いているので、そちらを参考ください。

https://qiita.com/Kudo_panda/items/62012f0c10e04b968074

あくまでも同じコンポーネントの同じVerを事業A、Bで友に共有する際に、
図のような関係性が成立するってこと。
すると、コンポーネントは事業Aとしての目的と事業Bとしての目的を担っている。
つまり、実質責務が２つあるといっていい。
責務が１つでないのはあまり推奨されていないが、それはあくまでも
【そのコンポーネントがまだ安定していると言えない】場合の話である。
安定していると言えるのならば、それは変更リスクが比較的小さいと言えるので、
１つのコンポーネントが２つ程度の責務を負うのは何ら問題ないと言える。

# 想定シーンを組織構造やVer管理に応用
上記の想定シーン(事業A、Bでともに同じVerのコンポーネントを再利用するシーン)で再利用コンポーネントを担当するチームなどといった組織構造まで考えてみることにする。

もう再利用コンポーネントは安定している状況を想定しているので、自分だったら次のように組織構造を設計する。
下図のように再利用領域以外を担当するチームと、再利用部分を担当するチーム。

<img width="650" alt="組織設計.jpg (69.5 kB)" src="https://img.esa.io/uploads/production/attachments/5827/2024/01/22/135213/755438e2-9ba0-4059-8d50-175e1954d18d.jpg">

でももしも途中で事業A、Bで違うVerを使いたいんだよねってなったら、この構造では無理がある。互換性の担保やら、Verの廃止計画やら、、、。

そこでもしも、事業Aと事業Bとで同じコンポーネント再利用したいけど、
それぞれ違うVerを再利用したいって時用に別の選択肢も考えてみる。
この場合には、コンポーネントは確かに安定はしているものの、
事業AとBでは、それぞれ異なるVerのものを再利用したいわけだから、以下のような状態になる。
<img width="500" alt="別バージョン.png (21.0 kB)" src="https://img.esa.io/uploads/production/attachments/5827/2024/01/22/135213/10974b9e-10f7-4001-a078-2f2498b59312.png">

再利用はしたいんだけども、Verが異なるってことは実体としては違うわけだから、
当然A用のコンポーネント、B用のコンポーネントって分けたい。
(注　もしも直近で両者のVerを揃えることが確定しているとかなら、
さっきのインターフェイス分離原則にしたがった構造の方が当然望ましいけど)

すると組織構造としては以下の構造になる。
<img width="600" alt="別組織構造.png (23.4 kB)" src="https://img.esa.io/uploads/production/attachments/5827/2024/01/22/135213/63399878-61cb-4596-b998-43aef80a6234.png">

図で見て分かるように、全然組織構造が異なる。
ソフトウェアだけの話ならVer管理とか含めて概念上でパッと変更すればいいだけだが、
組織構造をチャッと変えるのは非常に困難を極める。
そのため、他の事業でも再利用したいコンポーネントは、果たしてVerまで含めて共通と言えるのか？ということを常に考えながら組織構造までデザインできるようにしたい。

## 補足
今回は上記で、変更がほとんど入らないような安定しきっているコンポーネントを例にとった。
これは下図のプロダクトライフサイクルで言うと、成熟期以降の話である。
そのために、上では再利用コンポーネントを再利用ライブラリのように静的に結合させるやり方を取った。
しかしながら、まだプロダクトのライフサイクルが成熟期に突入していない段階では、
変更リスクが高くつく可能性が高いため、
上記のような再利用共有ライブラリ的なアーキテクチャは適していない。
<img width="500" alt="20180409185140.png (60.3 kB)" src="https://img.esa.io/uploads/production/attachments/5827/2024/01/23/135213/ca8ab0ff-6b75-4010-a3b6-984c539c616a.png">

このあたりの詳細は別記事の、マイクロサービスの再利用パターンの記事で書くことにします。