見積もりをがんばらない
スクラムを開発方法論に採用しているチームで開発者をしています。最近たまたま見積もりについての話題がチームであがり、私の経験や考えを整理してみる機会にしようと考えました。お断りとして、本稿の考え方が正しいと主張する意図はありません。世の中にはさまざまなチームや開発スタイルがあります。私が経験していない業務においては他のやり方もうまくいくケースがあると考えています。
スクラムガイド には見積もりの実践について明確な指針を提供していません。一方でスプリントを設定し、スプリントプランニングを行う上で通常はその期間内にスプリントゴールの達成を図ることから、必然的になんらかの見積もりを行うことを前提としています。インターネットを検索すると、プランニングポーカーとストーリーポイントを用いた見積もりの記事も多くみつかります。私の立場として、ストーリーポイントという見積もり手法をやや懐疑的にみています。この手法は一定の制約の中でしか機能しないのではないかと私は考えています。その理由や背景も後述します。
また、チームのスプリントにバーンダウンチャートが導入されました。バーンダウンチャートの運用についてスクラムマスターと議論していて、私の見解とは大きく異なることに気付きました。スクラムのルールとバーンダウンチャートの目的が合致せず、不思議に思ったのでそれについても後述します。バーンダウンチャートもスクラムには含まれません。
TL/DR (要約)
- (ストーリーポイントを用いない) 見積もりは担当者によって変わる
- 見積もりの精度は見積もり対象に対する情報量や知識量に依存する
- 見積もりはその見積もりを行った時点での予測に過ぎない
さらにまとめると言いたいことはこうです。
- 見積もりは外れるので常に補正していく
スクラムと見積もり
アジャイル開発とスクラム 第2版 で木下氏が書かれた「2020スクラムガイド改訂とスクラムの3つの罠」というコラムで、デイリースクラムの目的を次のように述べています。
デイリースクラムの目的は状況に合わせた再計画であるため、形式的な報告だけではいけない。
私自身、このコラムを読むまで勘違いしていました。デイリースクラムとは昨日やったことや今日やることの報告をするものだと考えていました。本当の目的は、なにか障害があったときにスプリントの計画を柔軟に再プランニングすることです。スクラムガイドにも「デイリースクラム」の節に次のように説明されています。
開発者が計画を調整できるのは、デイリースクラムのときだけではない。スプリントの残りの作業を適応または再計画することについて、より詳細な議論をするために、開発者は⼀⽇を通じて頻繁に話し合う。
スプリントゴールが変わるような再プランニングをデイリースクラムで議論するのは構わないと思いますが、ゴールに含まれないタスクやスプリントバックログアイテムの再プランニング (次スプリントへの先送り) は開発者が能動的に行えばよいのではないかと私は考えていました。しかし、スクラムマスターからは次のようなコメントをいただき、私の考えるスクラムの運用や見積もりとスクラムマスターのそれとは大きく乖離していることに気付きました。
- 基本的にはスプリントプランニングで立てた計画は変更しない
- スプリントの中止だけ唯一 PO に権限が与えられている
- スプリントの終了日にすべてやりきらなければならないということはない
- 検査/適用/透明性が実現できることが重要である
- バーンダウンチャートはスクラムには含まれない
スプリントとバーンダウンチャート
チームでは Backlog を用いて バーンダウンチャート を表示しています。
Backlog のヘルプセンターの概要には、バーンダウンチャートの意味や目的については説明していないので、バーンダウンチャートとは?意味やメリット、作り方のポイントを解説 の記事を読み解きながらバーンダウンチャートの目的や役割を次にまとめます。
バーンダウンチャートとは、マイルストーン (スプリント) の期間における、仕事量と時間の関係を表したものである。当初の計画と現時点の進捗状況がどのぐらい乖離しているかを視覚的に表現してくれる。グラフの傾きが進捗のスピードを表し、グラフが横ばいになると進捗が停滞していることを表す。バーンダウンチャートのメリットとして、計画と実際の進捗との乖離が明確になるのと、残された期間に対する仕事量の関係を視覚的に確認できることがあげられる。マイルストーンの完了後に当初の計画と実際の進捗との管理を振り返ることにも使える。
たしかにこの説明からも、スプリントにおいて完了できないタスクをそのまま置いておき、そのスプリントの振り返りの材料とする使い方はできるように読めます。またバーンダウンチャートの注意点として、次の2点があげられている。
- バーンダウンチャートは目安のひとつとして使う
- バーンダウンチャートでは表現できないメトリクスがあるので、これだけでプロジェクト管理はできない
- タスクをできるだけ正確に見積もれるようにする
- タスクの見積もりに正確さを欠いてしまうと、理想線・計画線と実績線が大きく乖離してしまう
- 「作業完了」の定義がメンバー間で異なると、仕事量の推定が不確かなものになり、適切なチャート運用を困難にしてしまう
バーンダウンチャートの適切な運用にはタスクの正確な見積もりが必要であると、この記事では説明されています。バーンダウンチャートを利用するのであれば、なるべく正確な見積もりとなるように努めるのは正しいでしょう。ここで、スプリントにおける、あるタスクの見積もりが外れたときに、そのタスクのマイルストーン (スプリント) を変更するかどうかでスクラムマスターと私では意見が分かれました。
スクラムマスターはタスクのマイルストーン (スプリント) はスプリント期間内では変更しないため、バーンダウンチャートはバーンダウンしなくてよいと主張します。一方で、私はバーンダウンチャートをみながら、マイルストーン (スプリント) に間に合いそうにないタスクはマイルストーン (スプリント) の変更を行い、スプリントが完了するときにはタスクがゼロになる、バーンダウンするのがよいのではないかと主張しました。
意見や考え方の相違そのものを私は気にしてはいません。しかし、スクラムマスターと私で見積もりに対する考え方が大きく異なることから、バーンダウンチャートの運用に食い違いが出ました。
本稿では、私の見積もりに対する考え方を説明した上でバーンダウンチャートの運用について述べます。
見積もりと不確実性コーン
そもそも正確な見積もりはとても難しいというのが私の経験則です。多くの人は共感してくれるのではないかと思います。大前提として、見積もりは誰がやっても外れる ものであり、一定のズレを織り込んだ上でプロジェクト管理を行うべきであると私は考えます。
私の経験では、見積もりと計画との乖離を過剰に責めるとメンバーが不正や誤魔化しを行い、結果的に品質が大幅に劣化して、後になってから (たいていは運用が始まってから) 大きな問題に発展することがありました。問題はわかった時点で対応する方がずっとコストが低くなります。品質管理の視点から見積もりのズレを誤魔化す必要は全くなく、そのズレを認識した時点で然るべき補正をしていくことが重要だと私は考えています。
見積もりの話題によく引用される図に 不確実性コーン があります。エンジニアリング組織論への招待 から引用します。
プロジェクトの進行とともに見積もりのバラツキがどのように推移していくかを表したものです。プロジェクトの初期は最大4倍程度のズレが発生する可能性があり、終了前ではほとんどズレないということを表しています。調べてみると、この図は1981年に発表されたものでウォーターフォール型開発の時代の話しだそうです。現代の開発で同様にみなしてよいか、検討の余地はあるかもしれません。一方で私の経験則においてもこの図のバラツキは一定の理があるように受け取れます。
私は次の要因によってこのズレが起きるのではないかと考えます。
- プロジェクトの初期は必要な情報が不足している
- プロジェクトの初期はメンバーのスキルが未熟である
- 情報もスキルもない状態では知識や知恵を得るのが難しい
そのため、プロジェクトが進むことで次のことが発生して見積もりのズレが補正されるのではないかと考えます。
- プロジェクトの初期と比べて、相対的に情報が増える
- メンバーが成長する (スキルや知識を身につける)
ストーリーポイントとプランニングポーカー
チームでも度々ストーリーポイントの話題が出るため、ストーリーポイントとプランニングポーカーという手法での見積もりについても考察します。
私はストーリーポイントもプランニングポーカーも実践したことはないため、この記事を読んだ程度の浅慮で書きます。そのため、本節の内容は誤っている可能性があり、参考程度に読んでください。
ストーリーポイントは、ストーリーポイントを実践できる状態のチームを先に作る必要があるのではないかと私は考えます。作業時間や工数をストーリーポイントに抽象化し、それをプランニングポーカーという手法で高い精度で見積もったとしても、そのストーリーポイントを誰でも同じぐらいの速度・品質でメンバーが対応できないと意味をなしません。というのは、どんな理屈を述べても最終的にストーリーポイントは作業時間や工数と対応付けられてしまうからです。現実の期限が10ストーリーポイント後になりますということはありません。
スクラムは属人性を排除して、メンバー全員がどんな作業でも同じぐらいの速度・品質でできることを目指すフレームワークであるというのは正しいと思います。しかし、現実の世界でその状態を維持するのはとても難しいのではないかと私は考えます。メンバーの知識やスキルセットには個人差があり、退職や移動などチームのメンバーは入れ替わります。そして、現実の業務にはドメイン知識や経験が必要とされ、その習得のために一定の学習コストを要します。1人でできる作業を複数のタスクに分割してメンバー全員が担当することによって属人化をなくすというのがスクラム的なやり方だというのは重々承知していますが、それを実践するには業務に対して過大なリソースを割り当てる必要があります。大雑把に言えば、1人でできるタスクを3つのタスクに分割して3人でやるような話しになるのではないでしょうか。大企業ではそういった働き方をしているかもしれません。
現実の世界では、特定の業務に対するドメイン知識やスキルは担当者個人に紐付いていることがよくあります。例えば、ある担当者 A が3年かけて身につけた知識やスキルを、3ヶ月ほどメンバー B や C に教えたからといって、B や C が A と同じことができるようにはならないことはあるでしょう。A, B, C でプランニングポーカーを行い、ストーリーポイントを見積もったとしても、A と B, C における実際の作業速度は大きく異なります。さらに本当は速度だけではなく、品質レベルも平準化しないといけません。しかし、品質は速度よりもさらに平準化が難しいです。
スクラム的な見積もり、ストーリーポイントとプランニングポーカーを実践するには、まずチームの知識やスキルセット、実践における品質レベルを先に平準化する必要があります。強いて言えば、過半数以上のメンバーの知識やスキルセットが高くない、深いドメイン知識を必要としない業務開発などに対してこの手法はうまくいくのではないかと思えます。私の知人からもそういう事例を聞いたこともあります。
ストーリーポイントのデメリット
【翻訳】ストーリーポイントを使うのをやめよう の記事では、ストーリーポイントの弊害についてまとめられています。2012年に書かれた記事でやや古く、いまの状況とあっていないこともあるかもしれません。この記事に出てくる成熟したチームで直感による見積もりを補正する程度でうまくいっている話しや著者の知人のベテランのアジャイル実践者のほぼ全員、何年もの間ストーリーポイントとベロシティ計算を利用していないと述べています。
これはストーリーポイントに限った話しではありませんが、測定される値に報酬が与えられるものはすべてが改ざんされるという キャンベルの法則 と呼ばれるものが、まさにこの記事で述べられている弊害のいくつかに当てはまるでしょう。さらにひどいことにストーリーポイントが誤解されてしまうと、その抽象化された概念の曖昧さゆえに誤解を正すために時間と労力を要するといったことも述べられています。
余談ですが、私の周りでストーリーポイントを実践していたり、その有用性を説く開発者はほとんどいません。
見積もりは担当者が決める
前節では、チームにおけるメンバーの知識やスキルセットが平準化されていない状態で、みんなで見積もることは役に立たないと私は述べました。本節では一旦、時間や工数といった従来のやり方で見積もるときの手法について考察します。
時間や工数を見積もる場合、見積もりは外れるという前提とともに、タスクの担当者が決めて補正していく やり方がもっともうまくいくのではないかと、私の経験則から考えています。X というタスクを、A は3日、B は5日で完了すると仮定します。前提として、X というタスクを A が担当するのか、B が担当するのかで見積もりは変わることを受け入れます。A が担当しても B が担当してもよいが、B が担当するときは3日ではなく、B の知識やスキルセットを考慮して5日という見積もりとします。
実際に B が X のタスクの作業をしていて5日では終わりそうにないことが、4日目にわかったとします。このとき、あと何日かかりそうかの再見積もりも他メンバーではなく、B が自分で見積もるようにします。見積もりが外れると同時に、B は再見積もりと一緒に振り返りの機会を得ます。認知心理学ではこのことを 活動中の振り返り (reflection in action) と呼んでいて、学習におけるメタ認知的活動の1つと分類しています。見積もりが外れたときの再見積もりには、それ自体を省察の機会とする狙いがあります。見積もりが外れることは構わないが、なぜ外れたかを振り返ることが重要であると私は考えます。
タスクの担当者に再見積もりを行わせる別の理由に、進捗中のタスクには情報の非対称性が生じやすいという背景があります。組織における情報の非対称性とは、マネージャーが知っていてメンバーが知らない情報が多いという状況を指すことが多いですが、現場の業務においてはその逆が生じます。B が担当者として作業しているタスクの状況を他メンバーがその実態を把握するのはとても難しいです。とくにソフトウェア開発はそうです。B が行った作業状況を最も理解しているのは B 自身であり、B が再見積もりする方が見積もりの精度が高くなる可能性が高いと言えます。
多くのケースで見積もりが外れるのは、想定していない状況や情報不足によることが多いです。そこで B は X というタスクを完了する上で必要な情報や気付きを得て学びにつながります。仮にその学びを他メンバーに共有したとしても、B の暗黙知を過不足なく他メンバーに共有することもまた難しいです。このような実務の1つ1つの作業がメンバーの知識やスキルセットの形成につながり、それをチームで平準化するためにやはり時間を要すると言えるでしょう。
見積もりは常に補正する
前節で見積もりは担当者が行うことを私は提案しました。さらに見積もりはプロジェクトやスプリントの開始時点で行うものと考えがちであるが、私はそのように考えていません。何度も申し上げているように 見積もりとは外れるもの という前提があるからです。
作業を進めていく過程でさまざまな情報を取得したり、たまたま担当者が体調が崩してパフォーマンスを落としたり、その時々の状況にあわせて担当者の状態が変化します。知識や情報量が増えることは見積もりを減らす方向に作用し、体調を崩すことは見積もりを増やす方向に作用します。担当者の状態が変化したときに再見積もりすることは、時間が経つと、より精度の高い見積もりになるという 不確実性コーン の理論とも合致します。
見積もりを自身の状態の変化にあわせて行うという考え方は、プロジェクトやスプリントの開始時点で見積もることとも矛盾しません。熟達者の見積もりの精度が高い理由は、見積もり対象のタスクの知識や情報を開始時点から他メンバーよりも多くもっているという点があげられます。
「エンジニアリング組織論への招待」の「プロフェッショナルの仕事」という節に次の図が紹介されています。
熟達者であっても未知のタスクをこなすときの初期の見積もりは外れることが多いはずです。しかし、熟達者は不確実性の高いものから取り掛かるため、作業の早い段階で全体像をみえるようにしてしまい、後半は品質の作り込みを行うだけなので未知のタスクであっても早い段階で精度の高い見積もりに補正してきます。一方で、経験が少ない人はわかる範囲から作業を進め、後半になってから不確実性の高いものに取り掛かるため、作業の後半になっても見積もりのズレ幅が大きくなってしまう場合があります。
ここでは不確実性が高いものとは、その対象に対する知識や情報が不足していると言い換えられます。タスクにおいて不確実性が高いものは何かを把握することにも一定の経験やスキルを要するのです。前節で、時間とともに見積もりの精度が上がる背景を、必要な情報の取得とスキルや知識の習得と考えました。もし作業の後半になって行った再見積もりのズレも大きい場合、不確実性の高い作業を認識できていなかったと考えられるのではないでしょうか。
見積もりは外れるという前提とバーンダウンチャート
スクラムマスターは、スプリントプランニングで決めたタスクの見積もりに対してどのぐらい完了できたかみるためにバーンダウンチャートを用い、バーンダウンしなくてもよいと主張しました。おそらくバーンダウンチャートがバーンダウンしなかったことはスクラムイベントのふりかえりで見返すだけという運用を想定しているのでしょう。この背景はプランニングでは正確に見積もることと決めたことができなかったという事実を重視していると言えるでしょう。
一方で私は 見積もりは外れる という前提から、スプリント中に日々バーンダウンチャートをみながら実際のタスクの進捗と見積もりとの差異を確認し、見積もりのズレから気付きを得てタスクの見積もりやタスクのマイルストーンを補正しながら、スプリントの完了までにバーンダウンチャートをバーンダウンさせる運用を想定しています。冒頭でも説明したようにデイリースクラムの目的は再プランニングにあります。スプリントプランニングで決めたことを重視せず、日々の進捗にあわせて変えていこうという実践を重視しています。
スクラムの目的である検査/適用/透明性を実現するために、チームにとってどちらがうまくいくかという議論のたたき台として本稿を書きました。
余談ですが、見積もりと関連して短過ぎるスプリントの弊害もあるように感じています。私が参加しているスクラムチームはスプリントを1週間にしていますが、メンバーの業務に対する習熟度が低いと適切なタスク分割ができず、タスクが1つのスプリントで完了せず、複数のスプリントにまたがって同じタスクに取り組んでいるということも常態化しています。これが常態化すると、スプリントでタスクをやり切るというタイムボックスの効果が薄れます。さらにプランニングは前スプリントに完了しなかったタスクが優先となってしまい、新たに追加できるタスクが少なくなることから、プランニングの意義が減ってしまうようにも感じています。
まとめ
個人的には、見積もりやタスクの完了にバーンダウンチャートが役に立つとはあまり考えていません。
本当の意味で、マイルストーン (スプリント) でタスクが完了しないことを、そのタスクの担当者はある時点から気付いています。こういった見える化したいという意図は、プロジェクト管理をする立場の人から、タスクの進捗が担当者との情報の非対称性によって分からないから見える化したいというモチベーションに基づいていると私はみています。そして、バーンダウンチャートをみて、そのスプリントにて、プランニングで決めたタスクが完了しそうにないとわかったら、プロジェクト管理の立場の人がタスクのマイルストーンを変えていくのがよいのではないかと私は考えています。スクラムで言えば PO でしょうか?
一般論として、タスクの担当者は、タスクが完了しないことを認めたくない傾向があります。タスクが完了しないことは見積もりや実務能力の未熟さを露呈するものなので、自身が無能だと思われたくないという心理が働きます。これは容易に品質を犠牲にしてもタスクを完了させたいというインセンティブに変わります。とくにまだ十分に時間がある中で間に合わないという判断を下すのは担当者にとってはある種の屈辱感もあります。
したがって、私はマネージャーの立場と責任においてタスクの先送りをするのがよいと考えています。タスクが遅延したのは、担当者が無能だからではなく、マネージャーが無理なスケジュールにタスクを割り当てたという体裁にしてしまうのです。しかし、スクラムにはマネージャーに相当する役割がいないので、担当者以外にタスクが間に合わないという判断を誰が下すのでしょうか。スクラム的にはチームで話し合って決めるというのが教科書に書いてあると思います。しかし、私はそれでもチームって誰ですか?と聞いてしまいたくなります。
リファレンス
アジャイル開発とスクラム 第2版 顧客・技術・経営をつなぐ協調的ソフトウェア開発マネジメント
最近、開発方法論や組織論に関心をもっています。2020年改訂スクラムガイド を読んだり、実際に業務でもスクラムを実践している開発チームで働いています。しかし、まだスクラム開発者として働き始めて2ヶ月なので新人です。これまで私はスクラムを実践している開発チームで働いたことがなく、いま初めてスクラムチームで開発者として実践しています。とはいえ、チケット駆動開発 + イテレーション開発 は10年以上実践してきており、厳密な定義では正しくないかもしれませんが、広義ではアジャイル開発という枠組みで開発を実践してきたと私の中では捉えています。そして、私の周りでうまくまわっていないスクラム開発をみかける度にチケット駆動 + イテレーション開発でうまくいくのになぜスクラムのような効率の悪い開発をしているのか?とすら内心では思っていました。
本書を読み終えて、結論から言うと、これまでの私の考えは誤っていたことが分かりました。スクラム開発が悪いわけではなく、スクラムをうまく実践できていない開発チームの諸問題を、スクラムがよくないかのように私が誤解していたと補正できたことが、本書を読み終えて私が得た最も大きな収穫と言えます。
(2020年改訂版の) スクラムガイドでは意図的に抽象的な表現を用い、役割と会議体のルールを定めた軽量な開発方法論のフレームワークを提供しています。そもそもスクラムとは、それ単体でうまく機能するような方法論ではないと考えるのが正しいようです。組織の文化、顧客、開発対象・規模など、様々な状況において柔軟にカスタマイズできるようなフレームワークです。そのため、一口にスクラム開発というカテゴリに括ることはできても、それは組織や開発チームによって千差万別であると言えるでしょう。
したがって、開発方法論がスクラムであるかどうかはあまり重要ではなく、スクラムをベースにしてもしなくてもいいが、開発がうまくいくように創意工夫や改善をし続けることが重要であり、スクラムはそのための下地としてのフレームワークを提供するにすぎないということが本書を読み進めていくうちに理解できました。
このことは第3章で木下文彦氏が書かれた「2020スクラムガイド改訂とスクラムの3つの罠」というコラムからも伺えます。私がスクラム開発を誤解していたように、スクラムを適切に実践できていない開発チームの特徴を3つの罠として述べられています。これまで私はこの3つの罠に陥っているようなスクラムチームを傍からみていて違和感を抱いていたと言えるでしょう。
3つの罠から1番目の例を取り上げると、デイリースクラムが形式的に情報を報告するだけになっているチームがあるとコラムの中では指摘されています。本来のデイリースクラムの目的は状況に合わせた再計画であり、形式的な報告はその副次的なものです。こういった目的を理解せずにただガイドに書いてあるからと状況報告するだけのチームも増えたのだろうと推測します。
余談: デイリースクラムのトレードオフ
私はデイリースクラムが現代の開発方法論において開発の生産性とトレードオフになっていると考えています。
まずデメリットから述べます。スクラムガイドではデイリースクラムを15分のイベントと定義しています。毎日15分会議してなぜ生産性が落ちるのか?と思う人もいるかもしれません。私が課題意識をもっているのは時間の長さではなく、チーム全員を毎日同じ時間に集めるという同期的イベントの発生そのものに懸念を抱いています。同期的イベントのデメリットとして次のようなことが考えられます。
- 集中して作業をしていても強制的に中断させられる
- 同期的イベントの前後30分ぐらいは集中力を要する作業がやりにくくなる
- 様々な理由でチーム全員集まらないことがままある
まずデイリースクラムを何時に開催するか?という大きな課題があります。朝10時にしているところも多いのではないかと推測します。私は朝型なので平均して8時ぐらいから始業しています。そうすると、集中して作業をしていても必ず10時に作業の手を止めなくてはいけません。そして夜型の人にとっては10時に参加することが難しいメンバーもいます。そういう人は遅刻したり午前半休することが常態化してしまうこともありました。13時にすればよいのでないか?となると、急ぎの報告をしたいときに13時では遅いため、デイリースクラムの前に打ち合わせをしてしまい、デイリースクラムを必要としなくなってしまう状況も起こりがちになります。こういう指摘をすると、朝会と夕会をやろうと言い出すマネージャーが現れたりして、さらに会議を増やすのかと私のような開発者はうんざりするわけです。とくに実務をやらないマネージャーほど、会議を増やすことに抵抗がなく安易にそういった提案をする傾向があるように思います。
またデイリースクラムという1日1回しかないイベントでしか進捗を報告しないメンバーの問題もあげられます。チケット駆動開発に慣れた開発者からみると、これでは報告が遅過ぎるように感じるのです。問題や懸念が発生した時点でチケットにその状況を記載し、それをマネージャーやメンターがみていれば、その時すぐにアドバイスや対策を検討できます。しかし、デイリースクラムでしか進捗報告をしないメンバーがいると、1日1回しかアドバイスや対策を議論できなくなってしまう懸念があります。それはメンバーの問題でしょうと思う方もいるかもしれません。しかし、私は知人からもこういった話しをたまに聞くため、特殊なケースではないと考えています。とくにメンバーのスキルが未熟なために誤った考え方や作業方針で進めてしまっている場合、1日1回の進捗報告では訂正がやりにくい状況というのがあります。スキル不足が原因の場合、メンバーは誤っているという気付きがないために報告できないのです。チケット駆動開発であれば、発生時に状況を伺う内容がコメントとして記載されるため、マネージャーやメンターがより迅速に状況を把握して訂正していくことができるのです。
ここからはデイリースクラムのメリットを述べます。スクラムを支持している方も安心してください。当然デメリットがある一方でメリットもあります。繰り返しますが、本来のデイリースクラムの目的は状況にあわせた再計画にあります。
想定外の状況が発生したため、スプリントのタスクを見直したり、ゴールを変更したりすることを比較的早いタイミングでメンバー全員で確認・合意できるところにあります。また先ほど、私がチケット駆動開発ならば書き込まれたコメントから状況を把握できると言いましたが、これをすべてのメンバーができるとは限りません。自分がやっていることを文章として書き表せるというスキルは、私が思っていたよりも習熟を必要とするスキルであり、開発者であっても全員ができるというわけではないことが経験則から分かってきました。書くスキルに加え、自ら情報発信するのが苦手なメンバーもいます。そういったメンバーは書くよりも話すことで情報共有できるデイリースクラムという場が唯一の救いであり (一方で義務でもあり)、聞かない限り状況を伝えるのが苦手なメンバーでも協働しやすいプラクティスと言えます。
さらに本書を読み進めることで著者の野中氏がナレッジマネジメントの古典となっている考え方として SECI モデルを説明しています。そして、SECI モデルの 共同化 (Sociallizatoin) がプロジェクトの起点であり、個人の暗黙知を他人や組織の暗黙知に伝えていくことの意義や重要性を説いています。起点が暗黙知であるならば、それはチケット駆動開発のようなコメントや文章として書くことはできないのです。
スクラムのイベントが多いのは個人の暗黙知を他人や組織の暗黙知に伝えていくための装置でもあるように私は受け取りました。そして、デイリースクラムもその暗黙知を伝えるための役割の一端を担っているはずです。だからこそ、儀式的に進捗を報告するだけのイベントには意味がなく、個人の暗黙知を伝える共同化という活動を促す必要があるのだと私は理解しました。
つまり、デイリースクラムは直接的には状況にあわせた再計画という目的をもちながら、中長期的には共同化という知識創造につながるプロセスも組み込まれているのです。単純に開発の生産性だけを理由にデイリースクラムは非効率だと断じるのは適切ではないと、本書を読み終えて私は考えています。
前置きが長くなりました。ここからは本書を読んで私が関心をもったところを抜き出して紹介します。
スクラムの起源と知識創造と組織
ソフトウェア開発方法論としてのスクラムはジェフ・サザーランド氏らによって定義され、スクラムガイドによってまとめられています。一方でそのオリジナルと言えるコンセプトは、野中氏と竹内氏が1986年にハーバード・ビジネス・レビューに掲載した The New New Product Development Game という論文になります。この論文はスクラムの直接の参考文献であり、スクラムの理論的基礎にもなっているそうです。
本書の「第10章 竹内・野中のスクラム論文再考」には野中氏と竹内氏のオリジナルの論文とソフトウェア開発方法論としてのスクラムの対比や考察が行われています。1986年という、日本の製造業が強かった時代に書かれた論文なので、いまとは全く時代背景が異なります。その時代背景も考慮しながら現代のスクラムとの共通点を見い出すことは、普遍的価値や概念を推し量る上でとても意義のあることだと私は思いました。さらに歴史を振り返ることでその是非を検証することもできるかもしれません。いま考えたことややっていることが正しいかどうか、本当の意味では、時間が経ってから歴史を振り返ることでしか検証できません。そして、オリジナルの論文とスクラムの間には多くの共通点があり、その意図している目的や概念を理解することでスクラムが意図する目的の理解もより進みます。
野中氏は2010年までこの論文のコンセプトがソフトウェア開発方法論として使われていることを知らなかったそうです。野中氏は組織や組織的知識創造理論の研究者であり、氏の理論が実際のソフトウェア開発の中でどのように発展してきたか、どのように要項が取り入れられているかなど、氏の研究にも意図せぬ相乗効果を生み出しているように私は読めました。そのため、スクラムの今後の発展形や拡張を推し量る上で野中氏の理論を学ぶことにも大きな意味があるように私は考えています。
また Scrum Inc. CEO であるジェフ・サザーランド氏のインタビューも本書の中で紹介されています。ジェフ氏はオリジナルの論文を1993年の終わりに作られた開発チームに取り入れたそうです。チームリーダーをスクラムマスターと呼び、機能横断チームを採用しましたが、最初はそれだけでは大きな変化をもたらさなかったように答えています。そして、第2スプリントでデイリースクラムを取り入れたらすごくうまくいき、第3スプリントでは生産性が最初の2回のスプリントと比べて400%にアップし、1ヶ月の仕事を1週間でやり終えたことが語られています。そして、そもそもジェフ氏がスクラムを体系化しようと考えた動機にも触れており、それは後半の実践知リーダーシップとはどういうものかにも係ってきます。
本書の前半では、ソフトウェア開発プロジェクトの背景や難しさ、スクラムの方法論やアジャイル開発における様々なプラクティス、大規模スクラムの話題などが書かれています。そして、中盤に事例紹介があり、後半は知識創造の背景や方法論について述べられています。とくに 実践知 という概念について説明されているところに私は関心をもちました。
実践知とは、アリストテレスが フロネシス と呼んだ概念であり、暗黙知と形式知との両方で構成されるものであると説明されています。そして、そこに身体性を伴っていないと実践知とは呼ばないというやり取りも野中氏のインタビューで話されています。「第12章 スクラムと実践知リーダー」を読んだだけでは曖昧だった実践知という概念が、その後のコラムやインタビューでのやり取りから、私はより理解できました。実践知は、考えることと行動することがセットになっており、自分の頭の中で考えているだけでは得られないものであることが明言されています。昔は 知行合一 と呼ばれていたものですが、90年代以降の日本は分析過多、計画過多、コンプライアンス過多になってしまい、そのことを忘れてしまっているという件には納得感がありました。
野中氏は日本的経営の強みとしてミドル層、中間管理職の存在をあげています。過去の日本においてはトップと現場に間の独特のポジションが政治力や知識の共有に影響力をもっていたと言います。そして、日本からイノベーションを起こしていくためにミドル層の役割が重要だとも話されています。しかし、この点だけは私は同意できませんでした。1980年代の日本においては中間管理職が大きな役割を担っていたかもしれませんが、私の経験からは中間管理職を不要とする組織を目指すべきではないかと考えています。中間管理職の大きな役割の1つにトップの考えや方針を現場に伝えることがあります。これは口頭で議論できる人数という物理的制約を伴うコミュニケーションパスの問題から組織階層が生まれたのではないかと思います。そして階層型の組織には情報の非対称性というとても厄介な問題があります。情報の非対称性は組織の理不尽を増大させてしまいます。だからこそ中間管理職が重要だという主張も理解はできますが、ICT 技術が発達した現代では別の解決策があるのではないかということを追求したいと私は考えます。その答えがティール組織やホラクラシーであるかどうかはまだわかりません。
合宿をしなさいという解決方法
「おわりに」という最後の結びに野中氏のこんなエピソードが紹介されています。2011年にジェフ氏とガブリエル氏がスクラムのトレーニングを日本で開催し、その際に平鍋氏と野中氏が飛び入りで参加したそうです。そして、参加者からの質問に対して野中氏が次のように回答したやり取りが紹介されています。
「プロジェクトには、営業部門、マーケティング部門、サポート部門など、いくつかの部門のステークホルダーがいるのです。そして、どの機能を優先すべきかについて意見が分かれているのです。意見を1つにまとめるには、どのようにしたらよいのでしょうか」
「合宿をしなさい」
「形式的な会議で決めることはできない。いろんな背景をもった人の集合において、形式知で語れること、理解し合えることはごく一部だ。合宿をし、一緒に飯を食い、泊まって徹底的に話しをする。そうすると、形式知は脱ぎ捨てられ、自分の主観で話すようになる。そこで、なぜこのプロジェクトに自分が参加しているのか、という根源的な問いにまでたどり着けるだろう。そこから初めて、1つの共通理解が生み出される。この過程をみんなで踏みなさい。」
この回答がどのような組織や状況においても正しいとは私には思えません。しかし、この回答は決して私が自分の言葉では語れない類のものであり、野中氏の唱える実践知リーダーシップがどういうものかを物語る一例として、私は衝撃を受けました。平鍋氏はこのことを伝えたいというのが本書を執筆した動機と書いており、その衝撃も理解できます。
一般論としてはなにかしら定量的な論理や多数決などで決めがちな難しい問題を、形式知では決められないと早々に認め、全く非論理的な解決方法を簡潔に提示しています。データサイエンティストが読んだらぶっ飛んでしまうのではないでしょうか。このような決め方に反発する人もいると思います。私もどちらかと言えばそちら側の方です。
おそらくこの手法の成否はリーダーとメンバーの関係性に依るのではないかと私は思います。最終的には論理ではなく、このリーダーに任せようという主観的な判断がメンバーに広がっていって結論を見いだせるように私は受け取りました。したがって、合宿そのものはその装置の1つであって、最終的には人間関係が決め手であり、チームまたはプロジェクトがよりよい関係を築くには実践知といった概念が不可欠になってくるのでしょう。
実践知の話題は心理的安全性や認知心理学の知見ともいくつか合致するところがあるように思います。合宿という手段を用いなくても、スクラムの中でそれに近い状態を再現できるようにしていくことが今後のスクラムを発展させていくということにもつながるのではないかと私は思いました。
More Joel on Software
過去にアリエル・ネットワーク (以下アリエル) という会社で働いていました。これはもう10年前の話で、アリエルはオンプレミスで運用するパッケージベンダーの会社だったので、昨今の SaaS のようなプロダクト開発とは状況が大きく異なります。そういった時代背景の違いを考慮して本稿を読むように注意してください。
当時の課題管理や開発方法論が、その前もその後も、10社以上、十数の開発チームで働いた私の経験の中ではもっとも開発の生産性も開発体験 (Developer Experience) も優れたものでした。
- アリエル・ネットワークでアルバイトをしてきました - forest book
- アリエル・ネットワークに入社しました - forest book
- アリエル・ネットワークを退職しました - forest book
たまたま、というよりは、私がお願いして、当時の上司と雑談してみました。当時のアリエルの課題管理システムには、自社パッケージの開発に関する内容 (プロダクトの機能開発や不具合など) だけでなく、顧客からの問い合わせや開発者のTODOやシステム管理のメモなど、会社の多くの情報が入っていました。プロダクト開発に関するすべての情報はたった1つのプラットフォームに集約されていたので情報の一元管理という視点からみると非常に強力なプラクティスでした。
多くの情報が課題管理システムに入っているので、営業もコンサルタント (アリエルでは顧客と開発者の仲介役) も、マネージャーも開発者も、そのチケット上でコミュニケーションをしていました。最近だと、チャットツールで他チームや他部署の人たちとコミュニケーションを取ることが多いと思いますが、アリエルでは課題管理システム上のチケットで行われていました。当時も Skype のグループチャットはあったものの、課題管理システムがコミュニケーションのメインで Skype はアナウンスなど補足的な用途でした。
そんな話題を上司としていたとき、あのやり方は Joel on Software に由来するのだと教えてもらいました。具体的には次の記事です (この記事は本書には含まれてなかった) 。
そんなきっかけで、私が Joel on Software に興味をもち、本書を読んでみた次第です。本書は2000年代に書かれた内容を出版したものなので、いまとなっては古典のような内容も多いです。とくに特定の技術について言及している内容は、当時の状況ではそうみられていたんだなとか、歴史的な読みものとして理解することも多いでしょう。本稿ではなるべくいまでも通用しそうな内容に絞って紹介することにします。私はいまマネジメントに関心があるのでその内容が多くなります。
第2章 優れた開発者を見つけるには
基本的に転職市場には優れた開発者がいないという前提を述べた後、次の方法を提案しています。
こちらから出向く
- ホットな新技術のカンファレンスに出かけて廊下をぶらぶらして会う人に声をかける
- 優秀そうな人をみかけたらスカウトする
自分のコミュニティを作る
- 似た考えをもつ優秀な開発者のコミュニティを会社の周りに作り上げる
- できればうまくいくが、コミュニティを作るのがとても難しい
これらはいまでも採用活動の一環として行われているようにみえます。最後のコミュニティを作るというのは、多くの会社がテックブログを書いていて、読者となる開発者の興味・関心を集めようとしているのがもう少し簡単な施策かなと思います。
またリファラル採用について、著者はそれほどこの採用方式を信用していないと述べています。
- 優秀な社員が優秀な開発者の友だちをもっているのは事実だが、優秀じゃない友だちもたくさんもっている
- 不採用になると友人関係にヒビが入るから本当の友だちを紹介しようとしない
- 最初の採用プロセスをパスする程度で新規採用のソースとしては最も弱いもの
- あくまで通常の採用プロセスをすべて通過するかどうかを判断基準にしている
リファラル採用よりも自社の採用プロセスを重視していることが伺えます。リファラルによって採用のバーが変わらないという点が大事なのかなと私は理解しました。
第3章 開発者観察ガイド
同僚はどんな人たちか?
著者がマイクロソフト社からもってきた採用ルールに、自分たちが付け加えたルールが次になります。
嫌なやつでないこと
アリエルの CTO もたしか飲み会のときに「アリエルの開発には嫌な人がいない」が仰っていた気がします。私も辞めるときにそのことを意図的に書いているので間違いないです。
開発者の視点からみたとき、一緒に働いている同僚に嫌な人がいなくて、同僚の技術スキルが高いというのが魅力的です。
昨今ではコンプライアンス対策からハラスメントを禁止する風潮もあり、若い人にとっては嫌な人がいないのが当たり前の職場しか経験していないかもしれません。それはよいことだと思います。いまは、技術スキルが高くて優秀な嫌な人になるのが難しい属性になっているように私は思います。それは技術の発展に伴う多様化・複雑化が要因の1つではないかと考えます。
2000年代はまだ1人の開発者がその事業部やチームがやっている技術の大半を把握しているといったことが、いまよりは可能でした。嫌な人だけど、技術スキルが高いから誰も文句言えないといった人が職場にちらほらいた気がします。
いまは技術の要素が多岐に渡り、それぞれが専門化・分業化したことでその事業部やチームがやっている業務すべてに熟達するのが難しくなっています。特定分野の技術スキルが高くても、他チームと協調したりお願いしたりすることが昔より増えました。結果として、嫌な人は活躍できなくなってしまい、そういう態度を取るデメリットの方が大きく、採用時点でも嫌な人特性を排除することを重視するようになり、いまでは淘汰されてしまったのではないかと私は思います。
いまは逆に、心理的安全性の文脈で、同僚に適切な厳しい指摘をするのが難しくなってしまった雰囲気はありますが。
心理的安全性は本来、思ったことを言える環境という意味な気がするが、一方で何も言えないというのは、なんかおかしいなと思ったり...知らんけど
— ヒデ・グク (@OgawaHideyuki) 2021年10月9日
誤解を招く表現だったので補足します。本来の心理的安全性の文脈では、同僚同士で適切な厳しい指摘をし合える関係のことを指します。しかし、それはお互いの信頼関係が前提になっています。そうじゃない状況において相手を尊重し、信頼関係を築いていくことから始めるでしょう。問題なのはそれがずっと続いてしまい、そのまま、ぬるま湯のチームが出来上がってしまうことです。メンバーが誰も厳しいことを言わないチームは永遠に問題ばかりをエスカレーションして、ビジネスの問題解決力に劣ったチームになってしまいます。
独立性と自律性
この考え方は、会社や組織、チームによっても解釈が変わってきそうな気がします。著者は優秀な開発者を次のように扱うべきだと述べています。
基本的に、頭の良い人を雇おうとするなら、彼らがその能力を仕事に適用できるようにしてやる必要がある。マネージャはアドバイスできるし、自由にそうしてかまわないが、その「アドバイス」が命令と受け取られないよう、細心の注意を払う必要がある。
(中略)
開発者は自らの能力によって雇われ、専門家として遇され、その専門領域に関しては決断させてもらえることを望んでいるものだ。
先日、上司と雑談したときも、課題管理システムの他者が担当者のチケットにコメントすると若い人は「命令」と受け取ってしまうのであまりしないようにしているといった話しを聞きました。チームで相談したり議論したりすることは良いことだと思いますが、なにかを決断するとき、その担当開発者が決められるようになっているか。みなさんの組織ではどうでしょうか。
政治がないこと
プログラミングの世界は非常に公正で、非常に厳格に秩序立てられている。そもそもプログラミングの世界に入ってくる人がそうする理由は、多くの場合、公正で、秩序があり、厳格に能力主義で、議論は単純に 正しいほうが勝つ ような場所にいたいと思うからなのだ。
プログラマが「政治」について文句を言うとき、それが正確に意味していることは、技術面よりも個人的な考えが重視されているということだ。
これも営業やビジネス部門がめちゃくちゃな機能や納期を要求してくるといったことは減ってきて、開発者が目の前の課題に集中しやすいようになってきたのではないかと、私の周りではそう思えます。しかし、業界や業種に依るのかもしれません。
プログラマが気にしないもの
彼らはお金を気にかけない。あなたが別なことでひどいことをしない限りは。
誤解のないよう、著者はプログラマの給与を低くしてかまわないということを主張していません。前述した通り、プログラマは公正さを気にかけるので、業務や能力に応じた適正な給与でないと怒りを覚えると補足しています。そのため、本節の内容は適正な給与を支払った上での前提であることに注意してください。
給与よりも業務内容や職場環境の居心地の良さを優先するので、給与の多寡は優先順位が低いことを理解しておく必要性を説いています。もう1つ、興味深かったのは、プログラマがこれまで不満を述べていなかった給与に言及するようになったら、その本音は給与ではなく、やっている仕事に不満をもっているという兆候であると述べています。要はやりたくない仕事をする代わりに見合う対価がほしいといった理屈だそうです。
さらっと書いてあったのですが、ソフトウェア会社の経営者は考慮しておくとよさそうに思えました。
第7章 一体化マネジメント法
著者の知っているマネジメント方法として3つあげています。
- 指揮統制マネジメント法 (軍隊のようなやり方)
- 入門経済学マネジメント法 (経済合理性を重視したやり方)
- 一体化マネジメント法
前の2つもそれぞれ章を割いて説明していますが、本稿では省略します。著者は自分の会社で一体化マネジメント法と呼ぶマネジメントのスタイルを取っているようです。いま聞くと、よく知られたプラクティスが背景に思い浮かぶ人も多いと思います。著者の名誉のために言及しておくと、この記事が書かれたのは2006年8月10日です。
入門経済学マネジメント法でやっちゃいけないマネジメントとして、内発的動機づけを外発的動機づけに置き換えてはいけないと強調されています。例えば、プログラマが自分からやりたいと考え、自律的に行動して改善した行動に報酬を支払うといったインセンティブを与えることです。これは 過剰正当化効果 と呼ばれるそうです。
余談ですが、最近、メタ認知に関する認知心理学の入門書を読みました。この本の中でも動機づけは次のような順番になるのがよいと書かれています。
- やる気のない段階 → 外発的動機づけ段階 → 内発的動機づけ段階
内発的動機づけによる行動に報酬を与えると、内発的動機づけを外発的動機づけに置き換えてしまい、外発的動機づけは内発的動機づけよりもずっと弱い動機になるので意欲を失わせてしまうことにつながるというわけです。その入門書では副作用のない安全な報酬として、ことばで褒めることを紹介しています。ことばで褒めても動機づけは置き換わらないことが知られています。但し、能力を褒めると失敗できないとプレッシャーになってしまう人もいるので、成果そのものを褒めるようにした方がよいそうです。
著者の言う、一体化マネジメント法は、この内発的動機づけを最大限発揮できるよう、社員の自律的に行動した結果が組織の目標につながるようにマネジメントの工夫をしているということでしょう。そのための施策として著者は次の2つをあげています。
- 昼食を同僚と共にする
- みんなに情報を渡す
後者は「情報の透明性」について言っていて、ホラクラシーやティール組織を成功させる要素の1つにもなっています。私の周りでは、比較的、小規模な組織では原則すべての情報を社員に開示することがプラクティスとして浸透している気がします。意図的にしろ、そうでないにしろ、情報の非対称性は組織の理不尽を増幅してしまうと組織論の本で読んだこともあります。これについてはあまり説明の必要はないでしょう。
前者の同僚と昼食を共にするというのどうでしょうか。私も過去に働いてきた会社では、だいたい同僚と一緒に昼食をとっていました。いま思い返すと、昼食を共にしていた上長や同僚と業務で対立したことがないことに気付きました。私は理屈の通らない業務やマネジメントにはクレームする方だったので、何度か上長と業務で険悪になってしまったこともあります。しかし、一緒に昼食をとっていた上長と険悪になったことは1度もありません。もしかしたら私の性格や考え方を上長が汲んでくれて、私が不満に感じないようなマネジメントをしてくれていたのかもしれません。
これもたまたまかもしれませんが、一緒に昼食を共にしていた同僚とは会社を辞めてからも繋がっていてやり取りしたりすることが多いです。昼食を共にしているうちに仲良くなるのか、仲が良いから昼食を共にするのか、どちらが真であっても、昼食を共にすることが悪い結果をもたらすことはないように私は経験から思います。意識したことはなかったのですが、本章を読んでいて、そういえばと気付いた次第です。
当然、著者もこのマネジメント法は難しく、うまくやるにはある種の深い対人スキルも要求されると述べています。そして、多くの職場では、場当たり的な、日により人により変わる「何でもあり」の方法でマネジメントされているという言葉で締め括っています。大企業では同じ会社でもマネージャーによってマネジメントが大きく異なるのが容易に想像できます。
第10章 コンピュータサイエンスの学生へのアドバイス
いくつかあるアドバイスの中で私が関心をもったもののみを紹介します。
卒業するまでに文章の書き方を学ぶこと
最も大きな権力や影響力をもつプログラマは、明確に、説得力をもって、やすやすと書き、話せる人間だ。
まぁまぁのプログラマと優れたプログラマの間にある違いは、アイデアについてコミュニケートできるかどうかという点にある。他の人を説得することで、彼らは力を得るのだ。
日記やウェブログをつけはじめるといい。書けば書くほど、書くのは楽になる。そして書くのが楽になれば、もっとたくさん書けるようになるという、プラスのサイクルができる。
私はいま「書くこと」そのものを再考しています。再考というほど、過去にちゃんと考えたことがあったのか問われると曖昧です。しかし、意識的に書く機会を設け、書く時間を割いて何かを考えるようにしています。あるとき、生産性の低い開発チームをみていて、ふと思ったことがあります。
よいプロダクトはよい開発文化から生まれる。よい開発文化は書くことから醸成されていくのではないか?
私は、いくつかの会社やチームで課題管理システムの利用を推奨し、日々のやっていることをチケットに書くことを促してきました。そして、自然に課題管理システムを使いこなす開発者が半分ぐらいしかいないという現実をみてきました。ここでは書かない人たちの理由は追求しませんが、情報の一元化や情報共有の文脈から書くことのメリットは大きいです。情報の非対称性が組織にとって弊害があることを多くの人が実感しているはずです。それでも書かない人たちはいるのです。
経験則では、書かない人たちと技術の多寡は相関がありません。そして、いま思い返すと、書かない人たちはチームで孤立しがちになります。これは周りが避けているわけではなく、その人は何をしているのか、何を考えているのかわからないので必然的に協働する機会が減り、結果として接する距離が縮まらないせいではないかと思います。
口頭と文章によるコミュニケーションでは次の特性があります。
- 口頭: 同期的で複雑ではない内容に対して数人程度でしか成り立たない
- 文章: 非同期でも可能で、複雑な内容も不特定多数へ伝えられる
つまり、口頭によるコミュニケーションコストはとても高いということです。そのため、チームのメンバー間で毎日やっていることや業務で考えていることを口頭で双方向に共有することは現実的にできません。例えば、それを課題管理システムのチケットにコメントとして書き込むのであれば、それぞれのメンバーの余裕のあるときに読めるのです。無論、読むかどうかはメンバー次第ですが。
その日々の積み重ねが中長期で開発の生産性をあげたり、チームの協調性を高めていくのに役立ちます。そのためにはメンバーが自律的に書ける必要があります。
もう1つ書くことのメリットをあげてみます。
後藤貴子の米国ハイテク事情 は Alan Kay 氏へのインタビューの内容です。その中で次のことを発言しています。
過去1世紀の電子技術のほとんどは退行的だ。というのは電子技術の多くは書くことよりオーラルコミュニケーションを奨励するからだ。昔、人々に読み書きを強いた多くのものは今は存在しない。楽しみのために読まなければ、恐らく必要になったときには読む鍛錬が足りていないだろう。書くこともどんどん不要になっている。将来はもっと、コンピュータが、“学ばないこと”の言い訳になるかもしれない。米国の多くの学校は、子供がGoogleで何かを見つけコピーすると、それで学んでいると思っている。しかし私は、子供がそれについての作文を書かない限り学んだことにならないと主張している。作文は思考を組織化する。単に博物館の展示物を集めるだけではない。しかしほとんどの学校はその違いを分からない。
氏は「作文を書かない限り学んだことにならない」と主張しています。書くことは記憶の定着とも関連するので学びの質を高めるように読めます。もし学んだことを自分の言葉で書けないのだとしたら、その内容について理解が欠けていることを自身で容易に判断できます。
これは私自身への戒めとして、このブログのアーカイブ数をみると、2009年から年間の記事数が減っていっていることがわかります。この理由の1つに、勤めていた企業のテックブログや他のプラットフォームで記事を書いたりしていたこともあげられますが、近年、私は書くことを軽視している傾向がありました。学びが減っているのと怠惰になっていることの両方あると考えています。
卒業するまでにミクロ経済学を学ぶこと
ミクロ経済学はビジネスで重要な理論すべての基礎となっている。需要と供給とか、競争優位とか、NPV とか割り引きとか限界効能について知らなければ、ビジネスの仕組みが全然理解できないからだ。
マクロ経済学は、当たっているよりもはずれていることの方が多い。スキップしてよい。
私自身、いま会社の経営も考えたりするので経済の基本的なことをもっと昔に学んでおくべきだったと振り返っています。著者によるとミクロ経済学より先の経済学はどんどん悪くなっていくのでやらなくてよいとのことです。本節を読んで入門本を読んでみようと思いました。後述する第34章でソフトウェアの価格づけを考察するときにミクロ経済学の用語も出てきます。
仕事がみんなインドに行ってしまうと心配するのをやめること
第1にビジネスの現在の流行に基づいて職を選択するというのはばかげている。第2に、仮にすべてのプログラミングの職がインドや中国に行ったとしても、プログラミングというのは、ビジネスプロセスエンジニアリングになる。第3に、これは信じてもらいたいのだが、非常に優れたプログラマというのはアメリカでもインドでもすごく不足している。
オフショア開発 - Wikipedia によると、1970-1980年代ぐらいにオフショア開発という移転が始まったそうです。2000年代はオフショア開発する企業が増えてきて、先進国でプログラマーの仕事がなくなるのではないか?という話題もあったように私も思います。しかし、いまはすべての業界の会社がソフトウェアを活用するようになった結果、プログラマの需要はまだまだ衰える様子はみられません。日本においても当面、プログラミングのお仕事は売り手市場になるのではないでしょうか。
第15章 ユーザビリティがすべてではない
そこには (少なくともユーザビリティのプロには) 恐ろしい一片の真実があった: 人々が本当に欲する何か本当にすごいことをやるアプリケーションであれば、無惨なほど使いにくかったとしてもヒットしてしまうのだ。そして世界で最も簡単に使えるアプリケーションであっても、みんなが望むことを何もしないのであれば失敗することになる。
多くの場合、ユーザビリティは実際オプショナルだということだ。
著者の会社は課題管理システムを開発しているので業務アプリケーションに近いパッケージベンダーになります。時代が大きく異なるので当時は見た目や操作性よりも機能の方が重要視されたように私も思います。バックエンドの機能がビジネスの差別化に直結していました。
ちなみにユーザービリティとユーザー体験 (UX) とは別の概念であると次の記事で説明されています。ユーザビリティはソフトウェア側の視点からの、特定のユーザーや用途において使いやすいことを指しているそうです。
ユーザビリティは「モノが持つ品質的特性」(実用的品質)であり、UXは「人が体験する感性的品質」であると言えます。
本章で著者が言及しているのは、ソフトウェアデザインの次の段階で、ユーザーインターフェースを正しく作ったら、ソーシャルインターフェースのデザインの方が重要であると言及しています。当時はソーシャルインターフェースのデザインについて系統だった学問はなく、新しい分野なので試行錯誤しているように読めました。
FogBugz では多くのデザイン上の決定が、1人で使っても有用であるようになされている。そしてチームの他のメンバにもだんだんと広まっていくのを促すようにデザインされた機能がたくさん組み込まれている。
FogBugz (課題管理システム) の顧客で、バグトラッキングシステムを全然使っていなかった顧客に FogBugz を導入して常用するようになった事例が紹介されていて、利用者がチームで仕事をするやり方が変わったことによると説明されています。ここでいうソーシャルインターフェースというのは、SNS のソーシャルではなく、チームのメンバー同士が協調する上で必要な機能やデザインを指しているように思います。
当時から10年以上経ってチームで協調して使うソフトウェアは進化したのでしょうか。私からみて課題管理システムに限って言えば、大きな変革があったようにはあまりみえないですね。
第20章 エビデンスベーススケジューリング (EBS)
途中まではアジャイル開発で言うところのベロシティを計測して、その値から見積もりの精度を上げる話しであろうと読み進めていました。課題を小さいタスクに分割し、個々のタスクの見積もりと実際の作業時間から速度を算出します。見積もりが正確であれば、速度は 1.0 に近付きます。例えば、見積もりより2倍の時間を要すれば、速度は 0.5 となります。見積もりと実際の作業時間がずれるのはよくあることなので速度の値がバラけることになります。ここでおもしろかったのが、速度をランダム値として、実際にかかる作業時間をモンテカルロシミュレーションで複数生成して、多少のズレがあってもどのぐらいの範囲の日程で終わりそうかの分布を確率的に求めていくというシミュレーション手法です。
スクラムなどでは次のスプリントで何ができるか、その達成に全力を尽くすというスタイルなのでスプリントを5回やれば何ができているかということは分かりません。著者の提案する EBS はちょっと先の未来を開発者が勘と経験で見積もるより信頼できる予測をモンテカルロシミュレーションで算出するといったものです。私は課題管理システムでこういった機能をみたことがありませんでした。プロジェクト管理の文脈ではいくつか記事が検索にヒットするのでこういった機能があるのですね。見積もりの精度が悪いチームではやってみるとおもしろいかもしれません。
その他、個人的に納得感が高いものが自分のスケジュールに次のためのバッファを用意しておくと述べているところです。
- 新しい機能のアイディア
- 競合への対応
- インテグレーション (他メンバーの作ったものと協調して動くようにする作業)
- デバッグのための時間
- ユーザビリティテスト (および、その結果を製品に反映させる)
- ベータテスト
もしかしたらパッケージベンダーだからこそ可能なバッファなのかもしれませんが、アリエルでも近いスケジュール管理をしていました。イテレーションにおける Feature freeze までの1.5ヶ月に対して必須機能を開発者に割り振り、それらを実装すれば、個々の開発者が (バックログから) 好みの新機能を自由に実装してよいというやり方でした。私の場合、2-3個の必須機能、2-3個の好みの機能、合計で5個前後ぐらいの新機能を実装していました。私の記憶では、3年間で開発チームが必須機能を期間内に実装できなかったのは1つだけだった気がします。つまり3年間でプロダクトとしての機能開発の遅れはほとんどなかったと言えます。
精度の悪い見積もりがためにスケジュールの引き直しを何度もやっているプロジェクトをみかけたことがあります。スケジュール調整のための管理コストもかかってしまうので適切なバッファの持ち方もマネージャーやプログラマに一定の経験を要求するのかもしれません。
第27章 バイオニックオフィス
開発チームのマネージャーはいいオフィス空間がどういうものであるかを知っているが、マネージャーの権限でオフィスを引っ越ししたり改装したりできるものではないのでどうすることもできないものだと考えていると述べられています。著者は経営者なので自分の会社のオフィス空間をいいものにしたいというこだわりが伺える内容でおもしろいです。建築士にブリーフ (ソフトウェア開発で言う要件) として提示した内容が次になります。
- 1人1人にちゃんとドアの付いた個室があることが絶対条件
- コンセントがたくさん必要、プログラマが新しいおもちゃを机の上でつなげられる
- データケーブル (電話、LAN、ケーブルテレビ、警報、その他) を床を這い回らずにつなげられる
- ペアプログラミングが可能であること (L字型の大きい机を用意する)
- 遠くのものを眺めて目を休められるよう窓を設け、ディスプレイを壁に向かって置いてはいけない
- オフィスはそこで時を過ごすのが快適なたまり場のような場所であるべき
現代ではデータケーブルの接続インターフェースはなくてもよさそうですね。一定規模以上の従業員が働く会社では個室は幹部のみでしょうし、最近は社員間の協調を優先してオープンなオフィス環境を重視しているイメージが私にはあります。たまり場について、日本人は休憩用途でたまたまそこにいる人たちとコミュニケーションを取ったりすることはあまりないように思います。それよりも、ちょっとした打ち合わせや小さい勉強会に、普段の会議室とは違う、ややくつろいだ雰囲気で行えるスペースがあるとよいように私は思います。
私はいまシェアオフィスを借りています。ドアのある個室で8割ほど満足しているのですが、2年近く使っていて、唯一不満だと思い始めたのがまさに窓がないことでした。窓がないと1日の時間の経過、天候の変化、季節の移り変わりに疎くなります。直接、業務には関係ありませんが、外から受ける刺激が少なく自然な気分転換にならないように感じるようになりました。次に引っ越しするときは窓のある部屋を借りようと考えています。
フィリップ・グリーンスパンは、はっきりこう言っている。「会社の成功は、ある部分までプログラマが実質オフィスに暮らすようになるかどうかにかかっている。オフィスが平均的なプログラマの家よりも素敵な場所である必要がある。そうする方法は2つある。すごくみすぼらしいアパートに住んでいるプログラマを雇うというのが1つで、もう1つは素敵なオフィスを作るかということだ」
学生時代に研究室に入り浸って過ごした人たちには馴染みがあるかもしれません。過去、私もオフィスに泊まり込みで働いたこともあったので環境がよいに越したことはないというのは理解できます。私は自宅で仕事をしない人だったので、自宅とオフィスの目的を明確にわけていました。一方で IT 業界ではリモートワークが普及しつつあり、私の周りではオフィスよりも自宅環境が快適で満足しているという友だちも少なからずいます。自宅とオフィスのどちらがよいか、個人差があるかもしれません。
第32章 心に残るカスタマーサービスへの7ステップ
ソフトウェア開発の本でカスタマーサービスについて言及している内容を私はあまり読んだことがないように思います。それだけで希少価値があるように感じますし、実際に内容も示唆を与えるものでした。
問題はすべて2通りの方法で解決する
ホコリを払うように勧める
- ユーザーに回答するときに言い方を工夫して相手を怒らせないようにするという話し
- キーボードが効かないというユーザーに「ちゃんとつながっていますか?」と聞くと、ユーザーは確認もせずにバカにしているように感じる
- 「接点のゴミがついていると接続が弱くなる。接点のゴミを吹き払ってからつなぎ直してもらえますか?」というと、自然にやってもらえる
顧客をファンにする
- 顧客が問題を抱えている時、それを解決してあげたなら、彼らは始めから問題なんかなかった場合よりもいっそう満足を覚える
- 私も過去にトラブル対応をして逆に顧客の信頼を得たことがあるのでこの考え方は支持します、ピンチはチャンス
- 顧客が問題を抱えている時、それを解決してあげたなら、彼らは始めから問題なんかなかった場合よりもいっそう満足を覚える
責めを負う
- 鍵のトラブルで「私のミスです。」と行った鍵前屋に対して著者は怒りの感情がなくなってしまった話し
- ミスを認めない姿勢や態度そのものにさらに腹が立つという話しに読める
言いにくい言葉を覚えておく
- 顧客からクレームがあったときの返す大事な言葉は覚えておいて、それを言う練習をしておく
- 例えば「私のミスです」、「申し訳ありませんでした。お代は結構です。」
- 心から言っていることが伝わる必要がある。だから練習をするのだ
操り人形の練習する
- 怒れる顧客の相手を感情的に切り抜ける唯一の方法は、彼らが怒っている相手は自分ではないのだということを認識することだ
- 怒られているのは自分という自然人ではなく、会社という法人だと置き換える
- 操り人形のように個人の感傷をなくして謝罪すればいいという話しに読める
- 私の経験では、過去に謝り方の下手な人は自分は悪くないと顔に出ていて顧客を逆に怒らせてしまう人がいた
- 当事者意識をなくさずに操り人形になるスキルは言うほど簡単ではないかもしれない
強欲ではどこにもたどりつけない
- 求人広告サービスで質問なしの90日間返金保証をしてうまくいった話しに読める
- クレジットカードで支払ったときに払い戻しに応じないとき、銀行に電話して払い戻させることができる。これをチャージバックと呼び、事業者側はチャージバック手数料を支払うことになる、たびたび起きると手数料が引き上げられることになる
- 顧客が払い戻しを要求したら結果は同じになるのでもめずにすぐ払い戻しに応じるという話しに読める
本章の内容はいまでも通用するように私は受け取りました。カスタマーサービスの問い合わせ内容を重視して、スキルの高い人を配置し、さらにその人たちのキャリアパスも用意しておくということをできているパッケージベンダーは少ないのではないでしょうか。テクニカルサポートは習熟するとキャリアアップのために辞めてしまうイメージが私にはあります。
第34章 ラクダとおもちゃのアヒル
パッケージソフトウェアの価格付けについてミクロ経済学の考え方を応用しながら論理的に考察していきます。著者がソフトウェア開発者も学んだ方がよいと助言するミクロ経済学の勉強にもなりますし、ユーモアのあるの文章で楽しめました。どういった属性の顧客にいくらで販売するのが利益を最大化できるかを次の手法を使って求めていきます。
- 需要曲線
- 消費者余剰
- セグメント化
- 正味現在価値 (NPV)
最終的にどういう価格付けになるのか。これから読む方のために秘密にしておきます。こういった考察を読むことで、ビジネスにおける数字の見方や考え方を学ぶ必要性も理解でき、経済学への興味へとつながるように思いました。本章を読み終えた後に気になって次の記事も読みました。
所感
一通り読んで、私が関心をもった箇所を書き出してみました。その過程でアリエルのよかったところが本書でも言及されている内容だったりして思い返すことも多々ありました。2000年代に書かれた本でも、学ぶべきところや時間が経ってもあまり変化がない内容もあります。私にとっては温故知新ということばがぴったり当てはまる内容でした。
エラスティックリーダーシップ――自己組織化チームの育て方
最近出版された本ではありませんが、じっくり読む機会があったので簡単に所感をまとめてみます。購入したのは約1年前でした。それから積ん読していて、読み始めてからも時間のあるときに少しずつ読み進めて1ヶ月ぐらいかかりました。
買っておくといつか読む可能性がある。
読まないよりは少しでも読んだほうがよい。
一通り読めてよかった。
。。。
そんな所感は誰も期待してないでしょうから、少し振り返りながら私にとって関心のある内容をまとめてみます。私はリーダーや管理職に就いたことがないので本当の意味では、本書のリーダーの難しさや悩み、葛藤などは理解できていないと思います。
一方でメンバーの立場でリーダーを補佐してきたことや、いくつかの企業やチームでそれぞれのリーダーに接してきたこと、自分にとって働きやすかったリーダーなど、やはり、本書を読んで共感できるところは多々あります。
そして、自分がリーダーとして振る舞うことが求められるとき、やはり、本書は人それぞれのリーダー観を獲得するヒントにもなるでしょう。
チームの自己組織化
本書でのキーワードの1つに「自己組織化」があります。聞いたことがあるような単語ですが、そもそも自己組織化とはどういう意味だろう?と思ったときに私は答えられませんでした。
パターン形成の仕組みを理解するために、物理学、化学、生物学、情報科学などに広く用いられる概念。無秩序状態の系において、外部からの制御なしに秩序状態が自律的に形成されることをいう。ここで「外部からの制御なしに」とは、外部から細かく手を加えてパターンを作成するような作用がないということを意味する。
いくつか説明の記事を読んで、コトバンクの説明が私にはわかりやすかったです。科学の分野にまたがって用いられる概念であるという。系をシステム、秩序をパターンやルールのように読み替えるとエンジニアリングの概念とも合致しそうな雰囲気はします。
それではチームの自己組織化とはどういう意味でしょうか。ちょうどその記事がありました。
この記事によると、アジャイルソフトウェア開発宣言 (Agile Manufesto) の一節に次の文言が出てきます。
最良のアーキテクチャ・要求・設計は、自己組織的なチームから生み出されます。
記事内では、単なる個人の集まりとしての共同作業グループと、その宣言で意図された自己組織化チームとの違いを、様々な特徴、モデル、要素などから説明しています。私がざっと読んだだけでは理解できそうにありません。私の中ではまだ言語化できていないので、ここではチームの自己組織化とは尊いものだとしておきましょう。そのぐらいの安易で、なんら初学者の理解を助けない表現で留めておきます。そして、チームの自己組織化は、簡単には成らず、成ったとしても永遠に続くものではなく、メンバーが相互に作用して目的を果たしていく形態のようです。
リーダーシップのスタイルとチームのフェーズ
チームには異なるリーダーシップを必要とするフェーズ/状態がある。本書では次の3つの関係を図解で表しています。
- 指揮官が必要なとき: サバイバルフェーズ
- コーチが必要なとき: 学習フェーズ
- ファシリテーターが必要なとき: 自己組織化フェーズ
図では「モード」と記載されているが「フェーズ」とも呼ぶと説明されている箇所があるのでモードとフェーズは同じ意味で捉えてよさそうです。
サバイバルフェーズ
本書では、チームに学習する時間が十分にない状態を「サバイバル」と定義している。リーダーはメンバーが学ぶ時間をとれるよう、サバイバルモードから抜け出すための戦略を練る必要がある。そういった状態では指揮統制型のリーダーシップが有効である。
学習フェーズ
十分なゆとり時間があり、その時間を使って学習や検証を行っているなら「学習」フェーズにいると言える。このフェーズにおけるリーダーは、メンバーに対して自分たちの問題を自力で解決できるように教え、挑戦させ、自己組織化チームへと育てることが目標となる。そのため、コーチ型のリーダーが必要になる。
自己組織化フェーズ
リーダー/メンバーともに何の心配もなく、携帯電話やパソコンの電源を切り、数日間仕事を放置できる状態であれば、自己組織化フェーズと言える。このフェーズにおけるリーダーは、ファシリテーターとなってその状態を維持すること、そして現状を処理するチームの能力に注意を払うことが目標となる。
フェーズ間の移動
チームの状態によってはリーダーシップが異なること、チームに発生するイベント、例えば、新人がチームに入ってくる、目標の期限を変更するといったイベントが発生したときにフェーズが移動することもありえると説明されている。
スタイルやフェーズに関する所感
リーダーシップのスタイルとフェーズにも「自己組織化」というキーワードが出てきます。他のフェーズと比べ、リーダーは自由時間をもち、メンバーは自分たちで意思決定を行い、チーム自身で問題解決できるという、尊い状態であることが伺えます。
本書では、それぞれのフェーズについて章を設けてより詳細に説明されています。その中で私が印象に残った5章の学習することを学ぶについて取り上げてみます。
学習することを学ぶ
学習モードとは、チームがゆとり時間を持ち、それを新しいスキルの集中的訓練にあてている状態と定義できる。
本書を読んで私がもっとも関心をもったことの1つに学習には「谷」があると説明されていたことでした。
進捗には2つのタイプがある。
- 学習の進みが遅く安定している高原。
- 学習が大きく飛躍している峰。
さらに引用します。
私が思うに、学習の真の力というのは、次の単純な事実を悟ることだ。谷は最終的には終わって、あなたは新しい知識と共に飛躍する ことになる。このことを知ってい れば、不可能だと思うことだって、やり始めることができる。
そして、自分が谷に直面している可能性があるのは次のような状況にあると言う。
- 面目や尊厳、お金や友人を失う可能性があるために、一歩を踏み出すのに勇気がいる。
- 違和感を感じている。
- 自分を変えるかもしれないこと、あるいは、自分の世界や仕事、関わる人々への理解の仕方を変えそうなことがある(が、これを事前に知るのは難しい)。
- 新しいスキルを獲得しなくてはならない。
真の学習は谷によってもたらされる。谷底は不快で、時折イライラさせられる。メンバーが楽しくなさそうなら、彼らをうまく安全地帯の外に出せている良い兆候かもしれない。メンバーから抵抗を感じたなら、それはあなたがうまくチームを操縦できている証拠だ。
余談ですが、先日、寺田さんの podcast に出演した際にも本書の学習の谷について少し話しました。
私はずっとバックエンドの開発に携わってきて、最近フロントエンドの開発に携わりました。その過程で自分の培ってきた経験や知識と明らかに考え方の異なる設計やアプローチに対して、大きな違和感を受けつつ、それを言語化できない自分自身のもどかしさに葛藤や逡巡を覚えました。
決して自身の経験や知識を正しいと主張して新たな開発スタイルを否定する気持ちはありませんでした。しかし、設計とはトレードオフを強いることもあるため、この設計ではこういうケースに対応できないとか、拡張するときにこういったデメリットがあるといった、大小あれども自分の価値観との違いをうまく言語化できずにもがいていました。
手伝い始めた当初はアンラーニングも大事だろうと考え、盲目的に同僚の意見や設計を受け入れながら開発を進めました。同僚はあまり設計やアーキテクチャを言語化せず、意図も説明しなかったので、違和感があっても指摘するのが面倒になって放置するといったときもありました。
そのときの楽しくない気持ち、自身の行動に自信がもてない気持ち、そういった感情の振れ幅とモチベーション管理をうまくできなくて自己嫌悪に陥ったときもありました。思い起こせば、これまでも新しいことに挑戦するときは同じような、うまくいかなくて挫折感を味わうというのは何度も経験していました。しかし、それを「学習の谷」という概念では捉えていませんでした。本書で谷という概念を知ることで少し救われたように私は感じました。
真の学習というのは、以前より生産性が落ちたり、違和感を感じて不快なものであると考えることにより、いくらか新しい挑戦への不安を軽減する術になるように私は思います。
第7章「メンバーを成長させる」にもリーダーがメンバーを指導するとき、メンバーにとって真の成長機会であるかを見分ける項目として、学習の谷にあることを確認するときの項目と同様に次をあげている。
- 恐怖があること
- 初期の不快感や不満があること
影響パターン
メンバーの主要な振る舞いを変えるように影響を与えたい場合の6つの影響力について次の説明があります。当初、この影響力のマトリクスの説明を読んだときはあまり内容を理解できていませんでした。
本書の後半は、様々なリーダーが1章ずつエッセイを綴っています。そのエッセイに対して著者が分析してコメントを書いています。そのコメントを読んでいると、このエッセイは影響パターンのこれとそれを示唆しているといった説明が度々でてきます。
より具体的な事例を影響パターンに分類することで私の理解が深まった気がします。
現場リーダーのための 6 つの原則 平鍋 健児
過去に平鍋さんの記事をいくつも読んで私は大きな影響を受けています。その中で「名前づけ」の節がおもしろかったので紹介します。
気づきによって得た知識に名前をつけましょう。
問題を解決する方法には、「ブレークダウンによる方法」(Divide and Conquer)と、もう一つ、「名前づけによる方法」(Name and Conquer)があります。
プログラミングで最も難しいことの1つに、やはり名前づけがよく言われます。私は初期の開発時にしょっちゅう名前を変えます。
名前を知ったことで人間の認知に影響が出たエピソードとして「ヨシュアツリーの原則」も紹介されています。
まとめ
読者の経験や立場によって本書の興味や関心をもつ箇所は変わるでしょう。また時間が経って、自分の状態の変化によっても本書から受け取る内容は変わるかもしれません。
さて、冒頭でチームの自己組織化とはなんぞや?という問いに、私は尊いという言葉で表現していました。本書を読むと、自己組織化とはこういった内容かなと、自分なりの解釈や理解が、読む前よりは進むように思います。そして、その解釈や理解に絶対というものもないように私は考えています。
私にとっての、チームの自己組織化というのは、チームが自律的に課題を解決していくための責任と権限をもち、それが開発文化として十分に根付いており、リーダーもメンバーもその役割を担う上での価値観が共有されている状態であると考えます。
できる 仕事がはかどるPython自動処理 全部入り。の第5刷が決定しました
昨年、ビジネスパーソン向けの Python 本を執筆したことを書きました。
おかげさまでまだコツコツと売れているようです。本書を購入していただいた方々、ありがとうございます。
このたび、第5刷の重版が決定しました。
【第5刷】7月17日(金)重版出来
出版してから1年ほどが経過し、今回の重版で発行部数が1万部を突破しました!
ビジネスPythonを学ぶ会の活動と slack の紹介
本書の読者サポートも兼ねて私が運営しているコミュニティがあります。
新型コロナウイルス感染防止の意図もあり、勉強会をオンラインで開催するようにしました。世の中的にオンラインで勉強会に参加することが一般化したせいか、オフラインで開催していたときよりも多くの人が参加してくれるようになりました。このままずっとオンライン勉強会を継続しようかと最近は考えています。
このコミュニティは難しいことを扱うわけではなく、またすぐに業務で役に立たないかもしれませんが、コミュニティとして長く続けられることだけを目標にしています。Python で困ったときに気軽に相談できる場になればいいなと思います。
本書の対象読者と同様、Python 入門を終えたばかり初学者、さらに IT エンジニアではない次の方々を対象としています。
いまのところ、月1回の勉強会を開くことを予定しています。オンラインでのコミュニケーションが取れるように bizpy.slack.com を開設しています。興味のある方はこちらの 招待リンク からご参加ください。
コミュニティの趣旨の詳細については次のスライドに整理したので興味がある方はこちらも参考にしてください。
次回からは Web API/SDK を扱う勉強会を何回かのシリーズで開催する予定です。本書では扱っていませんが、勉強会の参加者から Twilio というサービスがあると教えていただいたので次回は Twillo の API/SDK を取り扱います。
直接、本書にない内容であっても同じレベル・カテゴリに属する話題であれば勉強会の中で積極的に扱っていくつもりです。コミュニティなのでそういった参加者とのやり取り、そのとき流行っているもの、世の中の変化にあわせた話題などを提供できればいいなと思います。
私自身、普段の業務で扱っているビジネスや技術分野はとても狭いので参加者からそういった情報を教えてもらえることはありがたいものです。普段、接点がない人たちの視点や話からお互いに示唆をうけるような取り組みをさらに進められればと思います。
プログラミングできる人が増えること自体がいまの世の中にとっては良いことだろうと私は信じているので今後もそういった取り組みへのサポートをしていきます。
まとめ
プログラミングのスキルを身につけるには、一般論として、たくさんのコードを読んでたくさんのコードを書くことで習得できます。一朝一夕ではならず、日々の生活や業務に無関係だとなかなか行動に移すのが難しい場合もあるでしょう。
勉強会などは直接のスキルアップには結びつかないものの、スキルを学ぶきっかけ作りとして役に立つ場合があります。私自身、技術コミュニティへ参加しながらプログラミングを学んできました。
本書の出版をきっかけに「ビジネス x プログラミング」というテーマを考えながら1年ほど経過しました。しかし、まだまだ試行錯誤で今後の展望もみえていません。それでも勉強会を継続してきたことで少しずつ改善がみえ、ノウハウやコンテンツも積み上がってきました。いまはこのサイクルを継続することが次につながるように捉えています。
リファレンス
Pythonハッカーガイドブック -達人が教えるデプロイ、スケーラビリティ、テストのコツ-
マイナビ出版 さんから献本していただきました。ありがとうございます!
本書は初学者向けではなく、Python である程度プログラミングができるようになった後にスキルアップするための、中級者向けの書籍になります。昨今の流行りから言うと、例えば、データサイエンスに関わるデータサイエンティストやプログラマーがより実践的で効率のよいプログラムを書くことや、Python を使ったプロジェクトをうまくまわすための手助けになるでしょう。
本書では Python プログラミングでよく知られたプラクティス、ドキュメント作成、パッケージング、テスト、パフォーマンスの最適化とアーキテクチャなどが紹介されています。
著者の Julien Danjou 氏は、OpenStack という、巨大な Python プロジェクトのコントリビューターであり、チームリーダーを務めているようです。冒頭の「はじめに」のところでは OpenStack は900万行もの Python のコードで構成されているとあります。
単なる Python のテクニックのみを集めた書籍というわけではなく、著者の経験による、(ある程度の規模の) Python プロジェクトを通して Python をどのように活用してきたか、あるいは活用すればよいかの示唆を与えるような、目次からもそういう意図が伺えます。
本書からいくつか抜粋して私の興味・関心のある章を紹介します。私はこれまで何冊か Python の書籍を読んできましたが、その中で他の書籍ではあまりみたことがない内容を取り上げてみます。
第4章 タイムスタンプとタイムゾーンの処理
頻繁に扱う処理ではないものの、日時間の差を求めたいときなど、タイムゾーンはどうやって扱うのだったかな?と検索することが私は稀によくあります。もう同じことを10回以上は調べた気がします。本章でタイムゾーンをどう扱えばいいのかを学ぶことができます。
余談ですが、日時を扱う処理は本質的に複雑です。
自分が言えるのは、日時処理はそもそも本質的に複雑だという経験です。ざっと思いつくだけでも日時処理が複雑になる要因として次のような思いつきます。
- そもそも一貫性がない(月ごとに日数が異なる)
- 様々な基数(12進数、60進数、7進数?(曜日))
- 何の法則もない祝日
- 何の法則もない年号
- 複雑さに輪をかけるタイムゾーン
- 複雑さに輪をかけるうるう年
- 複雑さに輪をかける夏時間
プログラミングを教えるときなど、本質的複雑さとはなんぞやを説明するのに日時データを扱う処理をイメージするとわかりやすいので説明にもよく引用します。業務においても、こういった法則性もなく、なんらかの背景により条件が課せられるといったことは頻繁にあります。
閑話休題。まず Python の標準ライブラリで datetime オブジェクトを取得するとタイムゾーンの情報はもっていません。
>>> from datetime import datetime >>> datetime.utcnow().tzinfo is None True
タイムゾーンの情報を扱うには python-dateutil というサードパーティのライブラリを追加でインストールして使うのが一般的だと思います。
>>> from dateutil import tz >>> timezone = tz.gettz('Asia/Tokyo') >>> datetime.now(tz=timezone) datetime.datetime(2020, 5, 29, 20, 31, 26, 444650, tzinfo=tzfile('/usr/share/zoneinfo/Asia/Tokyo'))
例えば、サマータイムが終了するときはローカル時間では同じ時間が2回やってきます。1回目の時刻と2回目の同じ時刻を判別できるように fold という属性が Python 3.6 以降で追加されています。うろ覚えで見かけた気はしますが、自分でコードを書いたことがなかったので今回初めて fold を使ったコードを学びました。
>>> berlin = tz.gettz('Europe/Berlin') >>> confusing = datetime(2020, 10, 25, 2, tzinfo=berlin) >>> confusing.replace(fold=0).astimezone(timezone) datetime.datetime(2020, 10, 25, 9, 0, tzinfo=tzfile('/usr/share/zoneinfo/Asia/Tokyo')) >>> confusing.replace(fold=1).astimezone(timezone) datetime.datetime(2020, 10, 25, 10, 0, tzinfo=tzfile('/usr/share/zoneinfo/Asia/Tokyo'))
日本はサマータイムがないのでこういった処理を実装することは滅多にないでしょうが、知っておくと海外の開発者と一緒にお仕事をするときに役立つかもしれません。
第9章 AST、HY、Lisp ライクな属性
私の記憶では ast モジュール を説明している Python の書籍は滅多にありません。私自身、過去に ast モジュールの使い方がわからなくて調べたときがありました。
公式ドキュメントを読んでもモジュール内のクラスやメソッドの説明しか書いていないため、どういった用途に使えるものかよくわからなかったからです。
幅広い分野で利用されている Python の用途からすると、ast モジュールを使う機会は相対的に限定的であると言わざるをえないでしょう。したがって ast モジュールを説明する書籍は稀だと私は思います。
第9章の冒頭では、まさに Python の AST は十分に文書化されていないという背景から本章を設けたことが述べられています。そのため、本章は ast モジュールの使い方から Python の AST オブジェクトの解説も行われています。そして、ast モジュールの典型的な実用例としてコードの静的解析ツールである flake8 を拡張するサンプルコードが紹介されています。
最後に Hy という Python の AST を使って実装された Lisp ライクな言語を紹介しています。著者は Lisp 愛好家のようです。
Hy の話題は本当におもしろい取り組みだと私は考えていて、この言語は Python で DSL (マクロ) をどう実装するかの、実際に動く事例の1つであるからです。
$ pip install hy $ hy hy 0.18.0 using CPython(default) 3.8.1 on Linux
=> (defn hello [name] ... (print (% "Hello %s!" name))) => (hello "t2y") Hello t2y!
Hy の紹介を終えた後にその開発者である Paul Tagliamonte 氏のインタビューも掲載されています。このインタビューも示唆に富んでいて私は楽しめました。Python の AST はプライベートでもパブリックでもない曖昧な仕様であること、Python の実装やバージョン間によって AST が異なる可能性があること、Hy と Python の相互運用性は双方向にインポートできることから驚くほど高いことなどが述べられています。
現実の業務では、ast モジュールや Python の AST を操作するようなことは、静的解析やコード生成、特殊な事情における最適化など、ほとんどの開発者にはあまり関心のない話題かもしれません。しかし、言語処理系やプログラミングのことをより深く学ぶにはよい取っ掛かりでおもしろい題材になると私は思います。
本書は全体として実践的な内容をまとめたものです。しかし第9章だけは、どちらかと言うと、ハックを刺激する内容になっています。そのため、プログラミングが好きな開発者向けに楽しめる章ではないかと私は思います。
第11章 スケーリングとアーキテクチャ
ページ数は10ページ強と少ないのですが、アーキテクチャの話題を Python に特化した内容で解説しているのがよいと私は思います。プログラミング一般でもてはやされるアーキテクチャがその言語で必ずしもよい選択肢とは限りません。他言語のプラクティスをそのまま導入してもうまくいかないこともあるでしょう。
私はプログラミング言語の特性や、これまでの経緯を踏まえてそのプログラミング言語にあったアーキテクチャを採用するのがよいと最近よく思うようになりました。世の中の流行りを追いかけるよりも、その言語で培われた実績の積み重ねの方が優れている場合があるからです。
本章では歴史的な経緯も踏まえ、次の順番で説明されています。
マルチスレッディングの背景や制限を説明した後に、マルチプロセッシングや asyncio の話題に移っていきます。
asyncio が導入された背景として、それまで存在していた Python の非同期フレームワークやライブラリにおいて、各々における互換性や相互運用性を確保する標準的なイベントループインターフェースを提供することが狙いであったと解説されています。したがって、asyncio はアプリケーション開発者が直接使うというよりも、どちらかと言えば、フレームワーク/ライブラリの開発者が利用するモジュールのようにみえます。
そうとはいえ、asyncio とともに導入された async と await のキーワードや ネイティブコルーチン の概念など、アプリケーション開発者にとっても学ぶべきパラダイムはあります。
最後は ZeroMQ というメッセージキューを使って、マルチプロセス間での通信を行うサンプルコードも紹介しています。非同期/並行処理は、人間にとって難しく、なるべく言語機能やフレームワーク/ライブラリの機能を使いつつ目的の処理を実装するのが品質の高いアプリケーションを開発する戦略と言えるでしょう。
第13章 コーディングを減らしてコードを増やす
なんとなくおもしろい章のタイトルですよね。コーディング減らせばコードは減るはずなのに増やそうというわけです。これはどういうことでしょうか?
ある機能を汎用的に使えるようにしたり、ボイラープレート (繰り返し記述するようなものを指す) コードを減らしたりして、応用コードではそれらを再利用することで全体のコーディング量は減らしつつ、応用コードを増やすということを意図したタイトルなのでしょうかね?この章では次の内容を解説しています。
- sixを使ってPython 2とPython 3をサポートする
- PythonをLispのように使ってシングルディスパッチャを作成する
- コンテキストマネージャ
- attrsを使って決まりきったコードを減らす
これからは Python 2 の話は忘れてよいので six を使う場面はどんどんなくなっていくでしょう。コンテキストマネージャももう十分によく使われていますし、私もよくユーザー定義のコンテキストマネージャーを実装します。また監訳注にも補足がありますが、Python 3.7 で導入された dataclass は attrs からインスパイアされたものです。
消去法というわけでもありませんが、Python 3.4 で導入された ジェネリック関数 を定義するシングルディスパッチについて紹介してみます。導入当初は記事をよくみかけましたが、それから時間が経って最近はあまりみかけない気もします。
第9章でも述べられていたように、著者は Lisp 愛好家のようなので CLOS (Common Lisp Object System) と同様の方法でジェネリック関数をディスパッチする方法を定義しているシングルディスパッチの仕組みを Lisp の考え方と共に Lisp コードも交えて説明しています。Lisp でジェネリックな関数をどう扱うのかの雰囲気もわかっておもしろいです。
シングルディスパッチと関数のオーバーロード
シングルディスパッチができて何が嬉しいかを私なりに考えてみましたが、簡潔に言語化することは私には難しかったです。そこで考察したことをそのまま書いてみます。
この節では functools.singledispatch を扱う次のようなサンプルコードが紹介されています。これは実践的に意味のない、ただのサンプルコードでしかないのであまりよい例とは言えませんが、比較しやすいようにこのサンプルコードをベースに説明を続けます。
次の場所にここで説明するサンプルコード一式を置いてあります。
import functools class SnareDrum: pass class Cymbal: pass class Stick: pass class Brushes: pass @functools.singledispatch def play(instrument, accessory): raise NotImplementedError('Cannot play these') @play.register(SnareDrum) def _(instrument, accessory): if isinstance(accessory, Stick): return 'POC!' if isinstance(accessory, Brushes): return 'SHHHH!' raise NotImplementedError('Cannot play these') @play.register(Cymbal) def _(instrument, accessory): if isinstance(accessory, Brushes): return 'FRCCCHHT!' raise NotImplementedError('Cannot play these') print(play(SnareDrum(), Stick())) print(play(SnareDrum(), Brushes())) print(play(Cymbal(), Stick())) print(play(SnareDrum, Cymbal()))
play(instrument, accessory) という関数の第一引数 instrument によって呼び出す関数をディスパッチするようなサンプルコードです。このサンプルコードを別のアプローチで実装すると次のようなコードになります。関数型プログラミングとオブジェクト指向プログラミングで実装の違いはあれど、どちらも同じ機能は提供できます。どちらがよいという話ではありません。
class Instrument: def play(self, accessory): raise NotImplementedError('Cannot play these') class SnareDrum(Instrument): def play(self, accessory): if isinstance(accessory, Stick): return 'POC!' if isinstance(accessory, Brushes): return 'SHHHH!' raise NotImplementedError('Cannot play these') ... def play(instrument, accessory): return instrument.play(accessory) print(play(SnareDrum(), Stick())) print(play(SnareDrum(), Brushes()))
どちらのコードでも play(instrument, accessory) という同じ関数名を異なるインスタンスからも使えることに意義があります。ここではこのことをジェネリック関数と呼んでいます。後者のコードはポリモルフィズムと呼ばれたりします。
ここでそれぞれのインスタンスが受け取る引数が異なるパターンも考えてみます。説明をわかりやすくする意図で引数の数が異なる場合を考えます。
@play.register(Cymbal) def _(instrument, accessory, other): if isinstance(accessory, Brushes) and isinstance(other, Stick): return 'FRCCCHHT!' raise NotImplementedError('Cannot play these') ... print(play(Cymbal(), Brushes(), Stick()))
ジェネリック関数の定義では instrument と accessory の2つの引数しか受け取っていませんが、 Cymbal に紐づく関数でさらに other という3番目の引数を受け取るように変更してみます。結論から言うと、SnareDrum に紐づく関数では2つの引数を、 Cymbal に紐づく関数では3つの引数を受け取って意図したように動きます。
@functools.singledispatch の公式ドキュメントには型の違いによる、関数のオーバーロード の説明がされているので受け取る引数の数が異なっても動くのはただの実装依存かもしれませんが、ここでは関数のオーバーロードの説明をわかりやすくする意図で引数の数が異なるケースで続けます。
例えば、次のようなコードを考えます。
def add(x, y): print(f'{x=} + {y=} = {x + y}') def add(x, y, z): print(f'{x=} + {y=} + {z=} = {x + y + z}') add(1, 2, 3) add(1, 2) # この呼び出しはエラーになる
add() という同じ関数名で異なる引数を受け取る関数を定義したい場合、Python では関数のオーバーロードをサポートしないため、このコードでは後優先で3つの引数を受け取る後者の関数しか使えません。Python に限らず、動的型付け (ダックタイピング) の言語では実行時に型チェックすることから、関数のオーバーロードができるメリットよりも、呼び出し側が引数を間違えてしまったり、引数違いで同じ関数の実装が複数あることによる、コードの見通しの悪さといったデメリットの方が上回るからでしょう。
関数のオーバーロードがなくても、例えば、デフォルト引数を使うことでその目的は果たせます。これは引数が2つでも3つでも意図したように振る舞います。
def add(x, y, z=0): print(f'{x=} + {y=} + {z=} = {x + y + z}') add(1, 2, 3) add(1, 2)
しかし、デフォルト引数だと、受け取る引数のパターンが増えるとややこしくなるかもしれません。やっぱり関数のオーバーロードっぽいことがしたくなったとしても、例えば、次のようなデコレーターを使って簡単に実装することもできます。
import inspect class Overload: def __init__(self): self.namespace = {} def __call__(self, func): spec = inspect.getfullargspec(func) self.namespace[len(spec.args)] = func def wrapped(*args): f = self.namespace.get(len(args)) if f is None: raise NotImplementedError(f'Not defined for {len(args)}') return f(*args) return wrapped overload = Overload() @overload def add(x, y): print(f'{x=} + {y=} = {x + y}') @overload def add(x, y, z): print(f'{x=} + {y=} + {z=} = {x + y + z}') @overload def add(a, b, c, d, e, f, g): print(f'{a + b + c + d + e + f + g}')
このサンプルコードは引数の数だけに着目した関数のオーバーロードのデコーレーター実装ですが、これを汎用的にしたものが @functools.singledispatch という見方もできます。もちろん第1引数の型を使ってディスパッチする機能も使えるわけですが。
シングルディスパッチかポリモルフィズムかという議論は、複数のプログラミングの話題の背景を含んでいるように私は思います。
- 関数型プログラミングとオブジェクト指向プログラミングのアプローチの違い
- 関数オーバーロードを代替する実装の考え方の違い
- 型を意識して設計するときの考え方の違い
私は型システムに明るくないので適切な言い方ではないかもしれませんが、プログラマーの設計の考え方によってシングルディスパッチを好むスタイルがあることも理解できます。
余談ですが、私も過去に技術考察の一環で enum の定数固有メソッドを考察したときにオーバーロードの仕組みを実装してみたこともあります。用途によっては、関数のオーバーロードにより、コードの見通しがよくなるケースもあるのではないかと個人的には思います。
シングルディスパッチについての、私の結論としては、コーディングスタイルや設計の好みで使い分ければいいのではないでしょうか。
まとめ
私の興味・関心をもとに他の Python の書籍ではあまり出てこないような話題を取り上げてみました。
著者が Lisp 愛好家なので関数型プログラミングのプラクティスや話題が全体を通して出てくるところも特徴的かもしれません。本稿では紹介しませんでしたが、第8章は「関数型プログラミング」というタイトルですし、上述したように第9章では ast モジュールや Hy を取り上げていました。
Python は手続き型のプログラミング言語ではあるものの、関数型プログラミングの機能 (ライブラリ) もいくつか備えています。関数型プログラミングの考え方やアプローチを学ぶ上でも本書はよい入門になるように思います。
2020-06-13 追記
勉強会の LT で第8章「関数型プログラミング」の一部を紹介しました。
2020-11-21 追記
勉強会の LT で第9章「AST、HY、Lispライクな属性」の一部を扱いました。

Pythonハッカーガイドブック ~達人が教えるデプロイ、スケーラビリティ、テストのコツ~ (Compass Booksシリーズ)
- 作者:Julien Danjou
- 発売日: 2020/05/29
- メディア: 単行本(ソフトカバー)
できる 仕事がはかどるPython自動処理 全部入り。の第4刷が決定しました
昨年、ビジネスパーソン向けの Python 本を執筆したことを書きました。
おかげさまでまだ売れ行きは好調なようです。本書を購入していただいた方々、ありがとうございます。
このたび、第4刷の重版が決定しました。
【第4刷】3月16日(月)重版出来
Chapter 10 「065 Web ページを Selenium で操作する」の修正について
第4刷で本節の一部のコードが修正されます。 Selenium という Web ブラウザを操作するライブラリの使い方を紹介している節です。
これまでは Yahoo! JAPAN のトップページを題材として Selenium の操作を説明していました。
PC 版 Yahoo! JAPAN のトップページを 2019 年 10 月 1 日に刷新、 ... (中略) ... Yahoo! JAPAN トップページは 2008 年 1 月 1 日に大規模なリニューアルを行いました。その頃からある程度の改修はあったものの、基本的にはコードの継ぎ足しで修正を加えている状態でした。
なんと11年間変わらなかったトップページが2019年10月1日に大きな改善が入り、トップページの HTML の構造が変わってしまい、本書で説明している方法では動作しなくなってしまいました。
そこで第4刷では次のように Wikipedia のトップページに対して同じ操作を行うように変更しています。 申し訳ありませんが、第1-3刷を購入された方は次の内容に読み替えて Selenium の操作を確認してください。
変更した内容
まず、Wikipediaトップページの URLを指定してブラウザに表示させます。get()というメソッドを使います。
>>> driver.get("https://ja.wikipedia.org/")
検索語として「Python」と入力します。検索ボックスには searchInput というid属性が付与されているのでCSSセレクターで指定して、send_keys()でキー入力を送信します。
>>> driver.find_element_by_css_selector("#searchInput").send_keys("Python")
検索候補ウィンドウの検索ボタンにはid属性 searchButton が付与されているので、同様にCSSセレクターで指定して、click()でクリックします。
>>> driver.find_element_by_css_selector("#searchButton").click()
続けて、ブラウザの「戻る」を行ってWikipediaのトップページに戻ったあとに、"ログイン"というリンクを開いてみましょう。
>>> driver.back()
>>> driver.find_element_by_link_text("ログイン").click()
ビジネスPythonを学ぶ会の活動と slack の紹介
本書の読者サポートも兼ねて私が神戸で運営しているコミュニティがあります。 このコミュニティは難しいことを扱うわけではなく、またすぐに業務で役に立たないかもしれませんが、コミュニティとして長く続けられることだけを目標にしています。Python で困ったときに気軽に相談できる場になればいいなと思います。
本書の対象読者と同様、Python 入門を終えたばかり初学者、さらに IT エンジニアではない次の方々を対象としています。
いまのところ、月1回の勉強会を開くことを予定しています。地理的に参加できない方もいるでしょうからオンラインでのコミュニケーションが取れるように bizpy.slack.com を開設しています。興味のある方はこちらの 招待リンク からご参加ください。
いまは Excel ファイルを操作する openpyxl ライブラリの操作について取り上げています。そうすると、プログラマーではないけれど、企業でデータ分析の実務を行っている方々が参加してくれます。参加者の実際の実務で行っている内容をみんなで共有したり、参加者が書いたコードをもとにレビューしたり、私が開発やデバッグに役立つ手法を紹介したりといった、そういうゆるい感じの勉強会をしています。
今後も勉強会や読者サポートの過程でお伺いした内容や気づきを留めていき、いつか本書を改訂できる機会ができたときに活かせるように努めていきたいと思います。
まとめ
本書の出版を契機にして、これまで私が接点のなかった方々と Python プログラミングを通してお話する機会が増えました。
私自身、プログラマーとして10年以上働いてきて、ちょうどいまキャリアの棚卸しをしている時期です。今後は培ってきたプログラミングのスキルを活かして世の中の役に立つプロダクトやビジネスを創造することにも挑戦していきたいと考えています。ビジネスパーソンの方々が普段行っている業務や課題意識を知る機会があることは、私にとっては新鮮で興味深いものです。
またプログラミングできる人が増えること自体もいまの世の中にとっては良いことだろうと私は考えています。