- プロジェクトの見積もりや委任は、「これを作る」といった大きな依頼を明確なタスクリストに変えることから始まり、各項目は望む変化と完了状態を示す必要がある
- 分解のプロセスは、アイデア・スケッチ・初期リストから必要な手順を書き出し、各項目が十分に定義されるまで再帰的に細分化していく方法である
- 屋外活動向けのstreak trackerの例では、データモデル、カレンダー表示、活動記録、streak計算、streak freezeへと段階的に分かれ、不確実な点も同時に明らかになる
- 「十分に定義されたタスク」とは、望む変化、完了した姿、完了までのすべての手順、すぐに始めるために必要な情報のすべてにはいと答えられる状態である
- タスク分解は経験に基づくパターンマッチングが必要なスキルなので、初心者チームには計画を試し、フィードバックを受ける安全な練習機会が必要である
大きなプロジェクトをタスクリストに変える
- プロジェクト見積もりに関する既存の議論は、すでに明確なタスクリストがあることを前提としていたが、実際の現場ではその前段階であるタスク分解が先に必要になることがある
- タスク分解とは、大きなプロジェクトを構成タスクに分けるプロセスであり、見積もりや委任をするには「この絵を作る」といった単一タスクよりも細かい単位が必要である
- 1人で進める個人プロジェクトならスケッチだけでも十分な場合があるが、他人に任せたり期間を見積もったりするなら、粒度をさらに高める必要がある
例:個人用streak tracker
- 屋外活動をした日を追跡する個人用のstreak trackerが例として使われている
-
1回目:スケッチから始める
- 視覚的なモックアップは、作る機能を理解しやすく示すよい出発点である
- 1人で作るプロジェクトなら、この程度のスケッチだけですぐにコードを書き始めることもできる
- 見積もりや委任が目的なら、「この絵を作る」よりも細かく分けたタスクリストが必要である
-
2回目:大きな機能単位に分ける
- 最初の分解では、プロジェクトを大まかな構成要素に分ける
- データモデリング
- 現在の週の日付を表示するカレンダー表示
- アイコンをクリックして活動を記録し、その日をstreak追跡上の完了としてマークするインタラクティブなカレンダー
- 現在のstreakの長さの計算と表示
- streak freezeの実装
- 例を単純化するため、デプロイやデータベース設定のような運用作業は除外する
- 実際のプロジェクト、とくに複数人が参加するプロジェクトなら、デプロイ、フロントエンド、バックエンド作業を別項目に分けるほうが適切である
- この段階だけでもある程度の見積もりは可能だが、freezeの累積・追跡方法や過去の記録、活動タイプの追加・削除といった不確実性が残っている
-
3回目:完了基準が見えるようにさらに分ける
- データモデルは活動タイプ、記録された活動、freeze、streakに分かれる
- 活動タイプはrun/bike/ski/climbのようなハードコードされたリストで十分である
- 記録された活動は日付とタイプを持つ
- freezeは獲得日と使用日を持つ
- streakは開始日、終了日、活動タイプ別の集計情報を持つ
- 静的カレンダー表示は、週表示、ホーム画面、月表示、ナビゲーション、日付移動入力に分かれる
- 日付移動は複雑なfuzzy date入力なしに、HTML5 dateウィジェットを使える
- 動的な週次カレンダーは月表示に動的入力を入れず、特定の日付の活動タイプをクリックすることで完了記録を残す
- streakの計算と表示は、活動記録を走査してstreakを計算し、現在のstreakをUIに表示し、UIで活動を記録したらstreakを再計算する
- streak freezeは、累積、重複累積の防止、UIでの使用と残数表示まで含む
- freeze獲得基準のX日は、ひとまずハードコードしてもよい
- freezeは次のstreakへ繰り越せる
- 過去の活動を修正してstreakを再計算するとき、freezeを再び得てしまう重複累積を防ぐ必要がある
繰り返し適用する分解手順
- タスク分解は一度で終わる設計ではなく、反復的なプロセスである
- タスクリストや1つの大きなプロジェクトから始める
- そのタスクを終えるために必要な手順を考えて書き出す
- 各手順が十分に定義されているか確認する
- 十分でなければ、その項目を再び分解する
- 各反復は完全または正確である必要はなく、前のリストより少しでも拡張されていれば十分である
- すべてのタスクが十分に定義されるまで同じプロセスを繰り返す
「タスク」と「十分に定義されている」の基準
- ソフトウェア開発とプロジェクト見積もりにおいて、タスクとは十分に定義され、完全で、変化をもたらす仕事の単位である
- 「何かに取り組む」は要件の輪郭がないためタスクではない
- 「木を切る」は、チェーンソーを持ってきただけなら完全なタスクではない
- 業務の文脈では、タスクは実行後に何かが変わってこそ意味がある
- タスクが十分に定義されているかは、作業者が次の質問すべてに「はい」と答えられるかで判断する
- 望む変化が何かを理解しているか
- 「完了」がどのような姿かを理解しているか
- 完了までに必要なすべての手順を定義できるか
- ブロッカーや依存関係がないとした場合、今すぐ始めるために必要な情報をすべて持っているか
- 組織の文脈によっては、プロジェクトマネージャー、主要なステークホルダー、監査担当者のような観察者も、これらの質問に「はい」と答えられる必要がある場合がある
- バグ修正のように、これ以上細分化しにくい未知数を含むタスクもある
経験で培われる分解の感覚
- タスク分解は練習が必要なスキルであり、最初から簡単に感じられないのは普通である
- 例でデータモデリングを最初に置いた理由は、明確なアルゴリズムではなく、経験に基づく直感である
- 似たツールを作るとき、データモデルを先に固めるとうまく進んだ経験がある
- Djangoはモデルデータ優先の流れにより適したアフォーダンスを提供する
- 複数のプロジェクトを見たり実行したりした経験が不足していると、開始点を決めるのが難しい場合がある
- チームがこの能力を伸ばすには、安全な環境でプロジェクト計画を作り、分解してみて、フィードバックを受ける必要がある
- 初期計画が大きく外れても罰しなければ、その失敗は次回のパターンマッチングに使われる経験データになる
例示プロジェクトの見積もり結果
- ボーナス見積もりでは、タスクを細分化したあと、複雑度、不確実性、予想日数、最悪の場合の日数を付ける
- 全体の予想値は15.5日、最悪の場合は23.5日と計算された
- 主要項目のうち、streak計算とfreeze累積はmediumの複雑度とmoderateの不確実性で、それぞれ予想3日、最悪4.5日である
- freezeの重複累積防止はsmallの複雑度だがextremeの不確実性で、予想1日、最悪5日とした
- 実際には約12回の夜と長いフライト1回で完成したが、デザインを大幅に省略しており、freezeアルゴリズムには後で遭遇するバグがある可能性がある
1件のコメント
Hacker News の意見
まず、実際の手順を計画どおり最後まで実行できたことがほとんどない。数ステップ進むだけで新しい気づきがあったり、抜け漏れを見つけたり、もっと簡単な方法が見えたりして、計画には従わなくなる
次に、作り方を考える創造的な努力がすべて最初の部分に集中してしまう感じがして、こういう働き方が嫌いだ。残りも依然として作業の大半なのに、いちばん退屈な部分だけが残る。創造性と退屈さをもっと均等に混ぜたほうが楽しく、その分速く、結果も良い
この2つはおそらく関連しているし、自分がADHDである可能性もなくはない
自分のプロジェクトを探索したり作ったりしていて、特に責任構造がないなら、計画そのものが好きでない限り、そこまで計画する必要はない
しかし上司が「どれくらいかかる? 誰が何をする? どこから始める?」と聞いた瞬間、何らかの枠組みが必要になる
自分も恣意的だったり過度に硬直したシステムに合わせるのは嫌いだが、システムは単純で柔軟であるべきだし、生産性システムは人を助けるためのものだ
筆者はこれを詳細なレシピとして意図したというより、自分のアプローチを示して、他の人が自分なりのアイデアを得られるようにしたかったのだと思う
「計画は絶対にそのまま進まない」という話より、さらに悪い場合もある。実行中にタスクを追加し続けると、最後には計画時に作ったタスクと混ざり合って、もう必要のない未完了タスクのリストだけが散らかった状態で残る
そうしたタスクは、実行中に初めて生まれる全体の文脈なしに作られたものだからだ
プログラミングの面白さは、柔軟で流れるように進む創造的な活動であるところにある。進めながら作り上げ、有機的に経験していく
職場環境では監視と責任の所在が必要になるため、この有機性は主に取り除かれる
次に同じ、あるいは似た仕事を計画するとき、将来の計画はより良くなる
プロジェクトマネージャーにも「計画に失敗することは、失敗を計画することだ」という標語がある
覚えておくべき無数のことの中で、取りこぼしが多いとよく気づくからだ
計画とは、過去の自分が考えていた理想的な成果物を未来の自分に思い出させる方法にすぎない。際限なく計画を変えながら蛍を追いかける代わりに
「タスク分割」は、本のジャンルやポッドキャストのジャンルになってもよいほど大きなテーマだ。自己啓発や組織化に関する本を見ると、タスクを分割する活動を、読者がすでに備えている原初的な人間能力のように仮定していることが多い
しかし自分の経験やグループセッションで聞いた話では、タスク分割は非常に難しく、回避したい気持ちや絶望感を引き起こすことがある
自分が見た中で最も広く適用できる助言は、そのタスクを成功裏に終えられるという確信が**90%**に達するまで、さらに細かく分割し続けることだ。この確信度は自己信頼やリスク許容度によって変わるので、人によっては成功確率70%くらいまで分割することもある
1日に使える時間はおよそ6時間なのに、誰かが「半日」でできると自信満々に言っても、それは約3時間だと指摘すると、急にずっと自信を失ったり不機嫌になったりする。そして3日後にもまだそれをやっている
このやり方は時間見積もりでは驚くほど正確だった。ただし、合計で見ればそうであって、個々の見積もりは大きく外れる
結局は確率推定ということだ。多くの出来事を経れば平均に収束する
ほとんどの人が理解していない問題は、ソフトウェア開発が何よりも創造的活動に近いという点だ。もちろん真剣な技術的側面はあるが、問題そのものが仮想的で、土木工学のように現実世界の制約に縛られていないため、最適解が1つに定まらない
問題をきちんと見極める前に解法を定義しようとすると、最終成果物を制限するだけになる。探索の大半は、実際にコーディングを始めてから起こる
ソフトウェアでは、最終成果物と時間が明確に定義されていないことはそれほど重要ではない。単位あたりのコストがないからだ。ソフトウェア工学のバックグラウンドがない管理者は、これをあまり理解していない
汎用性のある製品は、追加の開発コストなしに複数の顧客へ販売できる
しかしほとんどの会社が工場のように運営されているため、あらゆる手続きは結局、特定の顧客を狙った非常に限定的な製品を生み出す。大手テック企業が避けたのはまさにこれだ
業界全体がこのパターンを受け入れているように見える
だが正直なところ、私たちの多くを妨げているのは、むしろそれをしない能力が足りないことだと思う。作りたいものがあるなら、すべてのピースを計画せず、価値があるかもしれない最小のものをそのまま作ればよい
例で言えば、「今日」画面と4つのボタンから始めればよい。毎日押す運動ボタン4つを表示するものなら、今日作れるはずだ。連続記録、凍結、カレンダー表示はなくてよい
そうしたアイデアはどれも良いし、後でやることになるだろうが、まずは勢いが必要だ。数日後には、そのカレンダー表示が気に入らないと判断するかもしれない
より多くのプロジェクトには、「小さくてもいいからとにかくやれ」という押しが必要です。今日終わらせて、その時点で次の作業が何かを見てください。計画段階で考えていたものとは違っている可能性が高いです
もちろん、これも簡単ではありません。最小のものを見つけ、気を散らさずにリリースすると決めるには、思考と規律が必要です。それでも練習する価値はあります
不確実性に直面したら「次にすべき正しいこと」に集中すべきだ、という原則です [0]
これを軽く見ようという意味ではありません。次にすべき正しいことを見極めるのは難しく、私の観点では計画の中で最も価値のある部分です
0: https://en.wikipedia.org/wiki/The_Next_Right_Thing#Synopsis
たとえば、1人がテスト用の比較方法を作り、別の1人があるアプローチを、さらに別の1人が別のアプローチを、3人目がまた別のアプローチを試し、決められた期間の後に全員で評価します
もちろん、すでに好ましいアプローチや明らかに優れたアプローチがない場合に限って意味があります
実際の開発では、モジュール化が並列化の方法になり得ます。人ごと、またはチームごとに1つのコンポーネントを担当する形です
私の作業では、特にまだ方向性を探っている段階では、人が触れる部分と技術的な内部を交互に進めるのが好きです。用途を知らないまま技術だけを開発すると、使える形が特定の方向に強制されますし、技術を知らないままインターフェースだけを設計することにも落とし穴があります
しかし研究のように、事前には分からないことを検証するために創造的な実験と 概念実証 が必要な仕事では、作業分解そのものが崩れます
そのため私は、概念実証の作業 の大半を非公開にし、誰にも話さない習慣がつきました
うまくいけば公開すればよく、うまくいかなければ面目を失ったり、続けるべきでないと確認した後でも何とか実現しろと言われたりすることなく、捨てて次に進めます
「Xの調査に3時間、Yに3時間、Zに3時間使い、その後で次に何をするかの計画会議をしよう」と言えばよいのです
結果は4つです。1つ目が解決する、2つ目が解決する、3つ目が解決する、どれも解決しない
少しの努力で解ける問題なら、2回目の試行、つまり6時間以内に解決する確率は50%です
そしてどこかの時点では、とにかくやるしかありません
作業分解と見積もりはほとんど同じものです。分解が終われば、数年の経験がある人なら小さな作業に対する標準的な見積もりを持っているので、各ピースに見積もりを付けるのに数分で済みます
私の場合は、自分が見積もれる塊に作業を分け、見積もれない部分は他の人の意見を求めます
ただし、熟練への本当の道が作業分解だとは思いません。誰でも悪い分解案は作れます
本当の熟練とは、その作業分解が問題を起こすほど間違っていることを証拠が示したタイミングに気づき、それを伝えたり 再見積もり したりすることにあります [0]
そして、そういうことが起こるのを気楽に受け入れ、変わる可能性の高いスケジュールを最初から出すことにストレスを感じないことも重要です
マネージャーはたいてい最初から正確なロードマップを欲しがりますが、それは不可能なことを求めているのです。良い管理とは柔軟性にあり、時間が経つにつれて開発者が学び、予想していた作業の性質が変わるのだと理解することにあると思います
文章の最後にある小さな例も考える価値があります。誰かが正確な見積もり、つまり「飛行機での移動中に夕食を何回か取る程度で終わる」と言っていたとしても、彼は危険すぎるとして断っていたでしょう
これは、見積もりが正確さだけの問題ではないことを示しています。そこにはリスク管理、期待値管理、作業への馴染み具合など、言葉だけでは表れない要素が多くあります
[0] https://jacobian.org/2021/jun/8/incorrect-estimates/ - このテーマについての記事もあります
彼らは優秀な新人ソフトウェア人材ですが、領域が新しいため、基本機能の立ち上げ方を本当に知らないことがあります。私の経験では、彼らは学び、うまくやり遂げられる作業を求めており、それが成長につながります
必ず覚えておくべきなのは、プロセスのコストはチームに合わせて調整する連続体だという点です。NBA選手は試合中のハドルでボールの投げ方を学びませんが、小学3年生の子どもたちは学びます
どちらの計画とコーチングも、それぞれのチームに合っているときに適切です
それがソフトウェア工学の核心的な真実なのかもしれません。筆者が作ろうとしている Streak アプリのオープンソース版がすでにあり、車輪の再発明をしているのかもしれません
脳はタスクリストを好まないようです。リストを作るのは楽しいこともありますが、創業やコーディングの大半は 探索 です
そしてタスクリストは探索を妨げます
そうでないなら、ソフトウェア開発では何が違っていて、私たちの職業では「分かりません」が妥当な答えになるのでしょうか?
それが正しい場合もありますが、そうでない場合もあります。「地図は領土ではない」
作業をより小さな作業に分けるには 重複作業 をしなければならず、コツはそれを最小限にすることです
不要な作業をまったくしないようにすると、結局すべてを一度にやらなければなりません
たとえば、BがAに依存するモジュールAとBがあるプログラムをリファクタリングするとしましょう。最も無駄が少ない方法は、2つのモジュールを一緒にリファクタリングすることです。しかしそれが最もリスクが高く、見積もりも難しいのです
分け方としては、Aをリファクタリングし、Bがリファクタリング後のAと動作するように合わせる、というもの。その後でAを再びリファクタリングすると、先に行った適応作業がすぐに捨てられるリスクが生じる。
捨てることになる作業をゼロにしたいなら、作業を分割できない場合が多い。20年の経験があっても、私は作業を分けるために捨てることになる一時的な作業をするのに、いまだによくためらう。
代わりに数週間がかりの作業をしながら、残しておいたヤクの毛を一本も残さず全部刈ってしまうような形になりがちだ。
始める前に解こうとしている問題について考えるのは理にかなっているし、大まかなマイルストーンも重要だ。しかし、たいていは未知の未知数が多すぎて、完全に分割することはまったく役に立たないか、不可能だ。
プロジェクトを分割するのにかけた時間を、そのまま解決策を見つけたり作ったりするのに使っていれば、ずっと早く終わった気がする。少なくともそう感じる。
私はたいてい別のアプローチを取る。そもそも作るべきかどうかを判断するために、投入する労力を見積もろうとしているのだ。いわば費用対効果の判断を助けることが第一の理由だ。
チームにとっても非常に有益になり得る。特に経験の浅い人たちと働くときは、作業をたくさん分けて並列化できる。
Jacobも自分のStreakアプリを実装するときには、こうした分解をそれほど多くはしていなかっただろうし、だから説明のために再帰的に例を挙げたのだと思う。
そういうときは、より小さな作業に分けて一つずつ終わらせるのが有用だった。そうすると行き詰まっていたり働きたくない状態でも前進が生まれ、その前進が続けるための推進力を作ってくれる。
管理者が速度を見積もれることにも、明らかに価値はある。ただ、一度味をしめると、「確実ではない」という言葉を本当に理解できなくなるのが問題だ。
私もコンサルタントなので、私たちが「アジャイル」に働くとしても、「これをこの時間内に納品します」と言うことは非常に重要だ。