mtx2s’s blog

エンジニアリングをエンジニアリングする。

組織設計の失敗に見るソフトウェア開発への悪影響

問題を抱えるソフトウェア開発組織を観察すると、その根本原因が組織設計にあると気付くことも多い。組織の構造的な歪みがまるで力場を形成するかのように、そこに配置された様々な要素に作用し、悪影響を及ぼしている。

組織設計のまずさから生じる問題というものはとらえ難く、理解し難い。その問題に気付かないから、真っ先に矛先がソフトウェアエンジニアリング領域へ向いてしまい、開発プロセスやソフトウェアアーキテクチャの改善を繰り返すが大きな効果が得られない。効果があったとしてもそれは一時的で、気付けば元に戻っている。

コンウェイの法則を思い出せばその従属関係に頷けるはずだが、多くの現場ではこういったソフトウェアエンジニアリング領域に閉じた施策に終始しがちではないだろうか。

以下に挙げる3タイプの組織問題は、ソフトウェアエンジニアやマネージャーとして私が実際に経験したいくつかの事例をタイプ別に集約したストーリーだ。複数事例の問題点を凝縮したため極端なストーリーになってしまった感は否めないが、その方が問題が強調されて理解しやすい。ここには問題の解決策が書かれていないが、失敗を回避するヒントや気付きを得るぐらいの価値はあると期待している。

プロジェクトチームとリソースプール

プロジェクトチームと呼ばれる体制は、どうやら多くのケースで"直感的に"採用される選択肢のようだ。プロジェクトの性質に適した人材をアサインできる柔軟さを持ち、それ故にクロスファンクショナルであり、スピード感がある、と。少なくともこの体制を選択する人たちは、そう信じているようだ。

これが全くの間違いだとは思わないが、最も基本的な制約と前提が考慮されていない。人材は有限であることと、いつだって多くのプロジェクトが並走しているということだ。

これらの事実から、プロジェクトチームがいわゆる「ドリームチーム」になることなど奇跡だ。プロジェクトマネージャーは、何とか頭数だけ揃えた体制でプロジェクトをスタートせざるを得ない。これで上手くやっていけるのか不安になる。やはりチームには、優秀なエンジニアにも参加して欲しい。

優秀なエンジニアは年中引っ張りだこだ。同時にいくつものプロジェクトを掛け持ちしている。そんな彼らから稼働時間を搾り取っても、せいぜい10%や20%程度が良いところだろう。その短い時間を使うことでさえ、彼らのスケジュールに合わせなきゃいけない。これがクリティカルチェーンとなって、プロジェクトのリードタイムを引き伸ばす。

プロジェクトを掛け持ちしているのは、なにも優秀なエンジニアだけじゃない。人員数に対し、プロジェクトの並列数が多すぎるのだ。誰もがプロジェクトを掛け持ちしている。掛け持ちするプロジェクトの数が多いほど、出席しなければならない会議体も多くなる。エンジニアはもはやコードを書く時間などほとんど残されていない。これでタスクを遅延させるなと言う方が無茶だ。何とか残業でこなすしかない。

残業で長時間労働が常態化すると、新しい技術を試したり学んだりする時間をエンジニアから奪う。実務の中で伸ばせるスキルもあるが、ソフトウェアエンジニアリングの世界で生き抜くにはそれだけで十分なのだろうか。技術も方法論も日進月歩だ。このままでは個人としても組織としても世界に遅れをとる。その上、プロジェクトチームはプロジェクトが終われば解散する。チームとして積み上げた能力もそこで失われるのだ。唯一の救いは、プロジェクトで得たナレッジをライン組織内で共有していることだけかもしれない。

エンジニアが所属するライン組織は、さながらリソースプールだ。プロジェクトが立ち上がる度にエンジニアを貸し出す。ラインマネージャーは、誰がいつからいつまでどのプロジェクトにアサインされるのかをスケジューリングし、管理する存在でしかない。どこかのプロジェクトで遅延が発生すると、プロジェクトから人員が解放される時期も遅れる。それがリソース計画を狂わせ、他の複数のプロジェクトに影響を及ぼす。マネージャーは、プロジェクト間でのリソース調整に常に追われることが宿命のようだ。

このような中でラインマネージャーはどうやってメンバーを評価するのだろう。メンバーは、日常的な業務をプロジェクト内で遂行している。その活躍ぶりをラインマネージャーが観察する機会は多くない。評価に対するメンバーの納得度は限りなく低くなるだろう。

モノリスチームという技術的負債生成器官

はじめは少人数のチームであっても、マーケットにおけるプロダクトの存在感が高まるにつれ増員を重ねることになる。そこからの道は二手に別れているが、その分岐にさえ気付かず、チームもソフトウェアシステムもモノリス化へと突き進んでしまう。そんなソフトウェアプロダクト開発組織もある。むしろ昔はその方が主流だったように思う。

このようなモノリスチームは、20~30名を優に超える大所帯を抱えた単一チームとしてソフトウェアデリバリ業務にあたる。

モノリスチームが育てたモノリスシステムは巨大過ぎて、我慢ならないぐらいビルドが遅い。こまめに統合していたら時間がいくらあっても足りなくなるから統合の頻度が下がる。継続的インテグレーションにはほど遠い。こんな有りさまだから、いざ統合しようという段階で問題が頻発する。

その上、バッチサイズは常に大きい。そりゃそうだ。チームサイズが大きいのだから、それに比例してバッチサイズも当たり前に大きくなる。そしてそれは、リリースリスクが大きくなることも意味する。リリースする度にトラブルを起こすので、CFR(Change Failure Rate)は酷いあり様だ。

チームにとってリリースは恐怖でしかない。そのストレスから逃れたいから、リリース頻度は下がる一方だ。残念なことにそれがバッチサイズをまた一段と大きくし、リリース時のトラブルは益々頻発することになる。

多発するトラブルを一刻も早く収めるよう、経営リーダーからプレッシャーを受けるのはマネージャーだ。もはやチームに任せてはいられない、自分が何とかせねばとマイクロマネジメントが常態化する。品質を上げたい一心で、マニュアルテストはより重厚になる。あらゆる開発フェーズには長い長いチェックリストが作られていく。それらが正しく実施されたことをチェックする承認フローまで設けられる。プロセスはより厳格で重厚なウォーターフォールになっていく。

かろうじて品質が安定しだしても、悲しいことに経営リーダーは喜ばない。リードタイムが長くなり過ぎたのだ。こんなパフォーマンスでは、ビジネスチャンスを掴めない。競合プロダクトに先を越され、マーケットでの競争力など無いに等しい。

その一方で、数多くのテストケースとチェックリスト項目に埋もれたチームメンバーたちは、自分がまるでマシーンになったように感じはじめる。指示されたことにただ従うだけの存在だ。規律正しいことだけが評価される。達成感も得られず、仕事は楽しくない。心血を注いできたプロダクトの競争力は無くなり、誇りも持てなくなった。そうして一人、また一人と会社を去っていく。優秀な人ほど先に辞めていく。

チームは欠員を補充しながら何とかこの鈍重なプロセスをまわし続けるが、初期からのチームメンバーが去った傷跡は大きい。システムがブラックボックス化してしまうからだ。小さな変更でさえ、その影響範囲の調査に膨大な時間がかかるようになる。詳細設計レベルまで進めないと開発規模を見積もることさえできない。だがそこまでしても、影響範囲の考慮漏れによるトラブルを度々発生させてしまう。

影響範囲を最小限にとどめたいから、消極的な設計が横行するようになる。既存コードや既存データにできる限り影響を及ぼさない設計を選択してしまうのだ。本来であれば既存のメソッドの変更で済むようなケースであっても、もとのメソッドを複製してそちらを変更する。こうしてコードの重複が生み出され続け、保守性は著しく悪化していく。

こんなことが巨大なバッチサイズでリリースの度に繰り返されるのだから、状況は酷くなり続ける。モノリスチームはまるで、技術的負債の生成器官のようだ。このネガティブスパイラルはいずれ、プロダクトを変更不可能な状態にまで追いやるだろう。

かろうじてチームに留まってくれた古参で優秀なエンジニアは、チーム内外から引っ張りだこだ。彼に聞けば安心だ、彼を通さないなら進めちゃだめだ、となる。そうやって属人化が進み、彼がボトルネックとなってリードタイムは更に悪化することになる。

低凝集チームが構成する分散モノリス組織

モノリスチームと対極にあるスモールチームならどうだろうか。7±2名程度のメンバーが固定で所属するチームが複数集まり、ソフトウェアプロダクトをマイクロサービスアーキテクチャやモジュラモノリスで分割統治する。このようなタイプの組織は今や珍しい存在ではないが、必ずしも上手くいくとは限らない。

複数チームと言っても人材には限りがあるから、必要な数だけチームを配置することは現実的に難しい。無理にチーム数を増やすと、一部のメンバーはチームを掛け持ちせざるを得なくなる。チームを掛け持ちするメンバーがいると、チーム間でのリソース管理が必要になる。掛け持ちメンバーによってチーム間が結合されているのだ。この調整によって、それぞれのチームのリードタイムが引き伸ばされてしまう。

一方でソフトウェアプロダクトのコンポーネント間は、依存関係を上手く設計したので結合度は低い状態だ。コンポーネントにはそれぞれオーナーとなるチームを決めており、コンポーネントへの変更はオーナーチームが担当する。どのコンポーネントでも自由に変更できるよう、オーナーを決めないやり方もあるが、そうするとコンポーネントへの変更でチーム間調整が頻発する恐れがある。複数チームで同一コンポーネントを同時期に変更することが起こり得るからだ。

これでチームが独立してコンポーネントを変更し、デプロイできるはずだった。しかし現実はそう甘くない。ひとつのフィーチャ開発で変更対象となるコンポーネントの数は、複数に及ぶことの方が多い。そのオーナーが単一のチームに収まらない。コンポーネントの変更に関してチーム間で調整する必要が頻発したのだ。

これは、各チームに対するコンポーネントオーナ権のパッケージングが適切ではないことによるものだ。チームとしての凝集度が低い、と考えれば分かりやすい。DDD的に表現すれば、コンテキスト境界が適切ではないということだ。

諦めて複数チームで協力して開発を進めることにするが、このやり方はチーム間にタスクの従属関係を生じさせる。一般的に、リードタイムを悪化させる主な原因としてタスクの従属関係が挙げられる。そのタスクの従属関係がチーム間で発生するのだから、リードタイムへの影響はなおさら酷い。あるチームにとっては優先順位の高いフィーチャ開発が、別のチームにとってもそうであるとは限らないからだ。チームはそれぞれにミッションや目標を持つため、チーム間で優先順位を揃えることは容易くない。

何とかスケジュールの調整を終えて開発を進めても、チーム間での開発スケジュールの合流ポイントで問題が起きやすい。従属関係にある先行タスクを担うチームの進捗に遅延が生じれば、後続タスクを担うチームにも遅れが連鎖する。ようやく両チームの成果物を結合すると、今度は両者の仕様の解釈に齟齬があることが発覚する。そしてその手戻りで更に時間を奪われる。

このような調整や齟齬が頻発するから、チーム合同でのミーティングが増えていく。2チーム程度であればそのコストも大したことはないが、コミュニケーションコストはチーム数の自乗のオーダーで大きくなる。チームが多いほどそのコストは組織に重く乗しかかり、ソフトウェアデリバリのパフォーマンスを削り取っていく。

「分散モノリス」という呼び名は、本来、マイクロサービスアーキテクチャアンチパターンを指すものだ。この名を組織タイプのラベルとして用いたのは、問題構造がよく似ているからだ。チームの凝集度が低いために、チーム間の結合度が高くなる。これが、分散モノリス組織の正体だ。

失敗から学ぶ

多くのマネージャーは、自ら組織を立ち上げるより既存の組織を引き継ぐことの方が多い。そうして担当することになった組織のパフォーマンスを全体最適の中で最大限に高めることがミッションだ。

その遂行には組織のリファクタリングが欠かせないが、いくつもの問題が絡み合って解決の糸口が見いだせないこともある。それこそが、本記事の3つのストーリーのように、組織の構造的な歪みによって生じる問題の可能性が高い。時には大胆に組織をリアーキテクティングすることも必要だ。

最後に、本記事で取り上げた問題のいくつかを列挙する。組織設計の深刻な失敗を回避するヒントや気付きになることを期待して。

  • 優れたプロジェクトチームが編成されることは稀だが、時間をかけてチームが成長してもプロジェクト終了と同時にその能力は失われてしまう
  • プロジェクトの掛け持ちはクリティカルチェーンとなってリードタイムを悪化させる
  • リソースプール化したライン組織では、マネージャーが正しくメンバーを評価することが難しい
  • チームメンバーの増加はバッチサイズを大きくする。それがリリースリスクを高め、トラブルを頻発させる。するとチームがリリース頻度を下げはじめ、バッチサイズが更に大きくなるというネガティブスパイラルに陥る
  • トラブルの頻発が続くとマイクロマネジメントが始まり、メンバーのやる気を奪い取る
  • ソフトウェアプロダクトを分割統治しない体制は、消極的な設計を横行させやすく、技術的負債を生みやすくする
  • 複数チームに分けてソフトウェアプロダクトを分割統治する体制であっても、チームの凝集度が低ければチーム間の結合度が高まり、コミュニケーションコストが高くつく。それがリードタイムを押し下げる

関連記事

参考までに。

プロジェクトチーム体制に関連する記事

note.com

mtx2s.hatenablog.com

モノリスチーム体制に関連する記事

note.com

mtx2s.hatenablog.com

分散モノリス組織に関連する記事

mtx2s.hatenablog.com

mtx2s.hatenablog.com

その他

mtx2s.hatenablog.com

note.com