ソフトウェア開発のプロジェクトにおける不確実性への向き合い方

ソフトウェア工学

この記事はMakuake Advent Calendar 2023の22日目の記事(ポエム)です。

概要

ソフトウェア開発のプロジェクトにおける不確実性について、自分が日々どのように向き合っているかを言語化してみる。

アジャイル関連の本を読み漁ったり、PMBOKの勉強をしたりと体系的に学んできたわけではないので、経験に基づいた主観的な話になる。

前提

自分がどのような環境で不確実性に向き合っているかを前提として話を進めたい。

私は技術基盤を設計・開発・運用するチームに所属しており、チームリーダー(プロジェクトをリードする責務とチーム内アーキテクトとしての役目を持っている)を務めている。

チームが取り組むプロジェクトは、

  • 自社開発
  • 他のシステムから利用されるようなシステムの開発
  • 比較的開発規模が大きい(1~2ヶ月で実装が完了するような工数ではない)
  • 中長期な期間(半年〜)を要する
  • 確定的な納期が定まっていない(要件に合わせた期日は決めるが、絶対的な期日ではない)

といった特徴がある。

受託開発であったり、よりエンドユーザーに近い開発を行うようなチームの場合は、不確実性に対するアプローチは異なるのではないかと思うところがあるが、根幹的な部分はどんなプロジェクトでも通ずるところがあるのではないかと思っている。(たぶん)

不確実性とは

不確実性への向き合い方について言語化する前に、不確実性についての定義を確認しておきたい。

不確実性とは一般に、「未来の出来事や状況を正確に予測ができない、難しい状態」のことを指す。

ソフトウェア開発におけるプロジェクトの不確実性もこの定義に当てはまると考えて良さそうに思う。

プロジェクトにおける不確実性の要因は様々だが、大別すると「外部要因」と「内部要因」があると考えている。

外部要因

プロジェクトの外側にあり、プロジェクトに影響を与える要因を外部要因と考えている。

市場の変化や法規制、自然災害などコントロールすることが難しい、あるいは不可能である要因のことを指す。

プロジェクトのメンバーやステークホルダーが頑張っても調整がつかないようなものは外部要因に分類される。

内部要因

内部要因はプロジェクトの内側にある要因で、プロジェクトのメンバーのスキルや、プロジェクトのスケジュール、プロジェクトの予算など、プロジェクトのメンバーやステークホルダーがコントロールできる要因のことを内部要因と考えている。

チームがプロジェクトにおいて向き合うべきは大抵この内部要因であると考えている。

外部要因と内部要因の間に位置づけされそうな要因もあると思うが、それはコントロールできるかどうか、優先的に向き合う必要があるかどうかを見極めて対処する必要があると思う

例がイマイチだったかもしれないが、外部や内部といった分類は重要ではなくて、不確実性への対処や防止のアクションができそうかどうかという点が一番の考慮事項かと思う。

不確実性が高い・低いとどうなるのか?

不確実性の高い・低いはプロジェクトの計画性に影響を与えると考えている。

逆にいうと、プロジェクトの計画性が高い状態だと不確実性を排除できている可能性が高く、低い状態だと排除できていない可能性が高いのではないかと考えられると思う。(もしかしたらそういう研究があるかもしれないが、ソースは探していないのであくまで自論である。)

計画性が高いと、リソース(人・金・時間など)の最適化、変更(計画、仕様、その他なんでも)への柔軟性、ステークホルダーの信頼関係向上などいくつものメリットを生む。

不確実性を極力取り払い、計画性を高めることがプロジェクトを成功させる上での鍵の1つだと思う。

不確実性を取り除くための前提として、計画性を常に観測・評価できるようにしておく必要がある。

例えば、プロジェクトの計画を表にしたロードマップやガントチャートなどプロジェクトの進捗を視覚的に把握・観察・評価できるものをチームの活動に合わせて用意する。

プロジェクトの計画性を評価するタイミング(スクラムならスプリントレトロスペクティブのイベントが丁度良いのではないだろうか。)で、何が計画性に影響を与えたのか?改善するためには何が必要か?などを振り返り、プロジェクトの進行に合わせて計画性を高めるためのアクションを実施する。特に何が不確実だったのか?を明らかにすることがチームにとって計画性を高めていくための学びであると考えている。

実務での例を何か取り上げたかったが、前提として共有することが多くなりそうで手間がかかりそうなので割愛する。

プロジェクトの計画性を評価するタイミングはチームによって様々だろうが、自分の場合は常に観察・評価するようにしている。いち早く遅延になりそうなこと(≒不確実性が高そうなこと)に気づけば、時間的な優位性を持って計画を見直したり、作業を調整したりすることができると考えているからである。

不確実性の見極め

不確実性を排除すれば計画性が高まり、ハッピーになれると語ってきたが、肝心の不確実性はどのように発見することができるのか考えてみる。

普段私はプロジェクトの中で、「わかっていないことを見つけること」を意識しているのだが、それを少し掘り下げてみると、要は「既知の未知」と「未知の未知」を見つけることなのではないかと考えた。

既知の未知

「わかっていないということをわかっていること」というのが既知の未知である。

例えば、ある程度仕様を把握している既存システムを別のシステムと連携する際に、利用すべきAPIやその呼び出しのシーケンスなどは見えているが、実際に連携した際にどのような不具合が生じるかわからないといったことが該当する。

既知の未知は、わかっていないことをどのようにしたらわかるようになるかを考えることができるため対処しやすい

未知の未知

「わかっていないということをわかっていない」ということが未知の未知である。

例を上げると、プロジェクトの進行途中で突然仕様変更の要求が発生するといったことが該当する。

未知の未知は、もはや予期しないことであるため、対処しにくい。事前に多角的な予測をする、時間的な余裕(バッファ)を持つなど投資的な対処が必要となる。

プロジェクトの中で「既知の未知」と「未知の未知」を発見・察知するために常に目を光らせておくことが大事であると考えている。

実際にどうやって発見・察知するかいくつかパッと思いつくところを書き出してみた。

  • プロジェクト状況の把握、観測
  • 経験に基づく勘
  • 野生の勘
  • ソフトウェア開発の一般論からのアイデア拝借

多分、演繹的だったり、帰納的だったりそういう思考プロセスをしているのではないかなと思うが、言語化するほど考えを整理できていないので、今後の課題にする。

不確実性への対処

不確実性を見つけることができたら、対処を検討する必要がある。

発見・察知した不確実性の対処方法について、いくつか持っているアイデアを言語化してみる。

  • 問題の性質を理解する
    • 不確実性の問題に対象するためにはどういう手順が必要だろうかを考える上で、まず問題を理解する
    • 最近知ったのだが、Cynefin Frameworkというフレームワークが考え方として参考になると思う
  • 戦略的に先延ばしにする
    • 先延ばしにすることが許容できる状況であることが前提
    • 「今はわからないが後でわかるようになる可能性がある」といった場合に先延ばしにするというのは有効な手段だと思う
    • 暫定的な対応をした上で先延ばしにする、というのも有りだと思う
    • どうでもよいが、「私は決断を先送りしすぎた」(『葬送のフリーレン』第13話「同族嫌悪」より)というフリーレンのセリフは身に染みるものがある
  • 学習する
    • チームが関わるドメイン、技術領域、その他環境により不確実性の種類や性質は異なるので、プロジェクトの中で検証や学習をする(≒アジャイル)
    • これは事後的な話で対処というよりは、今後類似の問題が発生したときに対処できるようにするという保険的なアプローチ

ケースバイケースだと考えているせいかあんまり思いつかなかった。。。

プロジェクトにおける不確実性を減らして計画性を高める例

不確実性への対処例として、タスクのプランニングを取り上げてみる。

  • タスクの分解
  • 完了定義
  • 共通認識の形成

タスクの分解

小さくタスクを分解することで見積もりがしやすくなるため、精度が上がる可能性がある。

タスクの依存関係も整理できていればタスクの並列化も考えやすくなる。 (タスクの分解可能性が低い場合はこの限りではない。)

タスクが大きければゴールやタスクでやることの認識もブレやすいので、そのような不確実性は極力排除したい。

完了定義

タスクがどういう状態になったら完了なのかを明確にすることは進捗の追跡、品質担保、リソース最適化(どのタスクを優先するか、時間を投資するかなど)などに役立つ。

タスクの完了定義を決めづらい、決めれれない場合はそのタスクの分解粒度が適切ではないか、あるいは不確実性が眠っている可能性があるのではないかと思う。

共通認識の形成

一定のまとまりのタスクを完遂するにあたり、チームメンバー間の共通認識のブレという不確実性があると思う。

タスクの分解粒度を考える上で、共通認識を形成することを意識すると不確実性の排除につながると思う。

例えば、何かの調査をするタスクがあったとする。

ex. 「〇〇の調査をする。〇〇の調査結果をドキュメントにまとめ、調査結果から〇〇を決める。」

このようなタスクにおけるブレとなるポイントは、調査の観点や調査結果のドキュメントの形式、調査結果から〇〇を決める際の妥当性、判断軸などがある。

このタスクは、

  • 調査観点決め
  • 調査
  • 調査結果の共有・相談
  • ADRの作成

などタスクを分解し、共通認識を持つマイルストーンを設定することでブレ(不確実性)を無くすことに繋がると思う。

あくまで一例なので、チームによって適切なアプローチは異なると思う。(上記は自チームでの実例。)

所感

不確実性への向き合い方について言語化してみたが、思ったより感覚的な部分に頼っているように感じた。

どこかで体系的に学ぶ機会があればまた思考を整理してみたい。

参考


関連書籍