📚

コード・システムの共通化の勘所について思いついたことメモ

2022/11/28に公開

tl:dr

  • コードやシステムの共通化はどうしても必要より過小または過大にやりがち
  • 本質的に、なかったときに苦しいところを共通化でどれだけ楽できるか、という観点。つまり他の投資判断と変わらない

詳細

共通化はソフトウェアエンジニアの宿命で、1-10ぐらいから話題になり10-100以降ではむしろそれが困難さの焦点になるイメージ。
過去に自分が関わったシステム構築のほとんどに共通化の話題があり、そしてどれもその方法に問題を抱えてきた。

問題の種類と実例

問題は2種類で、過大な共通化によって共通化することのコストが共通化しなかった場合のコストより上がってしまった例と、共通化をしなかったことにより共通化したときのコストより上がってしまった例。
前者は、より汎用的なシステムに作ろうとした結果、何でもできるがやるためには長大なDSLを書く必要が出てきたケースや、汎用的に作ったが結局それほどの汎用性は必要なく特定ケースのみサポートしていればいいことが後になってわかり、汎用化のための開発期間が事実上掛け捨て[1]になってしまったケースなど。
後者は、共通データベースパターンで[2]Spring Frameworkの複数のシステムがDBにアクセスしているにも関わらず、DIOを共通化せずコードが2重管理になり、DBのスキーマ管理コストが増加してしまったパターン。それによりテーブルスキーマの変更に大きなコストがかかるようになっており、システムの健全な改善を妨げていた。

考え方

共通化の話題は大ぶりになりやすい。というのは、実行が困難なためHowに目が行きがちなせいだと思う。
そのため、初めてやる人間は殆どの場合過剰に共通化へ投資してしまうし、逆に一度やってトラウマになっている人間は共通化を極力遅らせる傾向にある。

この共通化がどうしても極端になってしまう原因はどこまで共通化すればいいのかの判断が難しいことにあると思う。加えて、共通化というのは影響する範囲が1チームや1事業部に閉じず横断的になるため関係者が増えて政治が起こりやすい。結果、担当者の実績アピールのためにでかい仕事になりやすい(実はそこまで大きいものは不要であっても)。

政治の問題は一旦置いておくとして、共通化するかについては他のシステム開発と全く同じくRoIと比較の観点が使えると思う。つまり、以下のようなシンプルな問いが使える。

  • 共通化するコスト < (共通化しなかったときの既存システムのコスト - 共通化したときの既存システムのコスト)

これが成立する場合は共通化するべきだ。最も、 共通化しなかったときの既存システムのコスト(Life Time Cost LTC) は全体が数年、場合によっては10年以上に及ぶ場合もあるので難しいは難しい。ただ、少なくとも感覚で共通化の度合いを決めるよりは論理的な判断基準になると思う。

この式は共通化の度合い(どの程度共通化するべきか)を考えるのにも有用だ。
共通化の度合いを強めれば強めるほど 共通化するコスト は増えていくが、同時に 共通化しなかったときの既存システムのコスト - 共通化したときの既存システムのコスト も変わる。例えば、2つのシステムの共通性が非常に高い場合、 共通化するコスト を増加させるよりも早く 共通化しなかったときの既存システムのコスト - 共通化したときの既存システムのコスト が増えていくはずだ。言い換えると、先程の式を変形した

  • 共通化しなかったときの既存システムのコスト - (共通化するコスト + 共通化したときの既存システムのコスト)

これが最大化される共通化の度合いを選べば良い。
例えば、変更頻度がそれほど高くないDBスキーマの共通化であれば共通lib gemやJarファイルによるDIOの共通化だけでいいし、逆に変更頻度がとても高いのであればマイクロサービスAPIでコストを払ってもペイする。それは、前述の式を最大化する観点で選べる。

まとめ

僕が関わったシステムはどれも共通化に問題を抱えていた。それは僕が設計の全責任を持ったシステムも同様である。共通化を失敗したシステムというのは長く組織の足を引っ張り、回復させることには途方も無い労力が必要なことが少なくない。そのような悲劇を少しでも減らせるよう、現時点での自分の考えをここにまとめた。

sponsored

この記事はSpeeeでの業務中に書きました。

脚注
  1. それどころかシステムコードが増えて複雑になった結果、むしろやらなかった場合より価値の低いシステムになってしまっている ↩︎

  2. そもそもこれが良くないという話があるがそこは論点ではないので一旦放っておく ↩︎

Discussion