私のとっておきのプログラミングスタイル
2007.09.15
404 Blog Not Found の「LiveCoding に学ぶプログラミングの三原則」を読んでいたらどうしても書きたくなったので。あくまで私のスタイルなので、参考にするもしないもご自由に。
1. スタードダッシュでできるだけはやくめどをつける
学生時代から夏休みの宿題は7月中に終わらせていた私とすれば、ラストスパートよりはスタートダッシュで勝負する。どのみち、どこかで思いっきり頑張らなければならないのであれば、締め切り間際ではなく、スタート間際に頑張るべきというのが私のポリシー。十週間のプロジェクトであれば、最初の二週間が勝負。そこで八割がたのめどをつけておき、後は流す。最初の二週間がめどが立てられなければ、十週間で完成できる可能性は低いと考える。常にそういう姿勢でいれば、締め切りぎりぎりになって致命的な欠陥が見つかって痛いめにあったり、本当は大幅な設計変更をすべきなのに応急処置ですます、などの可能性が減らせる。
このスタードダッシュ型の仕事スタイルを実現するには、「締め切りに迫られて」ではなく、「自分から進んで」スパートをかける必要がある。以下はそのための手法。
2. 仕事を「タスク」に細分化する
プログラマーである私にとって、一ヶ月は「気の遠くなるような先」。そんな先を目指していてはすぐに息切れしてしまって走ることができない。そこで、仕事を細分化する。ここでの仕事の一つの単位(便宜上「タスク」と呼ぼう)は半日から三日ぐらいで出来るもの。最初にすべきものほど明確に定義し、後でやるものはある程度曖昧にしておく(どのみち設計変更はするので、あまり先のことまで綿密に計画を立てるのは時間の無駄)。
3. 一日の始めに、「今日やるマイクロタスク」のリストを作る
これはすなわち、当面取りかかるべきタスクのさらなる細分化(マイクロタスク化)である。大切なことは、各マイクロタスクが独立した作業で、それが達成できたかどうかが(テストプログラムなので)明確に確認でき、かつ、それを一塊のものとして(ソースコードを管理しているサーバーに)チェックインしてもサイド・エフェクトがないこと。大きさとしては、うまく行けば15分ぐらいで、なかなかうまく行かなくても二時間ぐらいで完成できると思えるぐらいが適切。ちなみに、サイド・エフェクトの考慮は大切。相互に依存するモジュールAとBに同時に変更をかけなければ問題が生じるのであれば、モジュールAへの変更だけを独立したマイクロタスクとして定義することは不可能。
そんなマイクロタスクを数個から十数個並べたリストを机の上に書いて、それぞれにチェックボックスを添えた上で、例えば「今日は昼飯までには最初の4つ、家に帰るまでには残りの7つを絶対終える。余裕があったら、次の2つもこなす。」と自分で宣言する。
4. それぞれのマイクロタスクは「割り込み禁止状態」でこなす
大切なことはマイクロタスク一つ一つを「決して他の仕事を間に挟んでは出来ない仕事」と覚悟して、全力疾走でこなすこと。その間はメールのチェックはしないのはもちろん、電話がかかって来ても取らない。トイレにも行かないし、席から立ち上がりもしない。誰かが机に来ても、「今はだめ」という。脳を100%そのマイクロタスクに集中し、一気に書き上げる。つまり、マイクロタスクを処理している時にコンテキスト・スイッチをしてはいけないのだ(割り込み禁止状態)。
大切なことは、この「割り込み禁止状態」と「割り込み可能状態」をはっきりと区別して一日を過ごすこと。「割り込み禁止状態」におけるプロダクティビティを最大化できれば、その比率は4:6(つまりプログラミングをしている時間が4割)ぐらいでもものすごく仕事がはかどる。逆に常に割り込み可能状態でプログラムを書くと効率の悪さ故に、残業しても、一日の90%の時間をプログラミングに費やしても大して仕事がはかどらない。この割り込み禁止状態でマイクロタスクをひとつづつこなすという仕事のスタイルに体が慣れていれば、どうしても仕事量を増やさなければならない時には、その比率を8:2ぐらいまで増やした上で仕事時間を長くすれば良いだけのこと。何日も続けると体が持たないし、周りの人に迷惑をかけるが、2〜3日ぐらいのダッシュなら二週間に一度ぐらいはかけられる。
5. マイクロタスク単位に丁寧にテストした上でチェックインする
順調に書き上げることができれば、自分なりのテストをして、それが確実に動いていることを確認した上でチェックイン(「1つ書いては動かせ」というやつ)。それから休憩するなり、メールのチェックをする(割り込み可能状態)。チェックインする単位ごとでのテストは手を抜いてはいけない。このレベルでのバグを発見するのは、プログラムを書いた本人の役目。テスターの役目ではない。テスターの役目は、どうしても生じるプログラマーが見つけ損なってしまったバグを見つけること。「たぶん動くだろうけど、バグがあったらテスターが見つけてくれるからいいや」という考えでチェックインするのは犯罪行為。
6. うまく動かないマイクロタスクは、一度最後にチェックインしたところまで戻って書き直す
そんなマイクロタスクを実行中に、ある部分のソースコードを大きく書き直したくなることがあるが、そこは躊躇せずに思い切ってする。万が一そのためにプログラムがぐちゃぐちゃになってしまったら、ケチケチせずに、最後にチェックインしたところまで一気に戻ってやり直す。マイクロタスクが十分に細分化されていれば、そこで「捨てるコード」に費やした時間は高々1〜2時間。一度ぐちゃぐちゃになったコードを直す方がよっぽど時間がかかる。
変更した箇所が思った通りに動かない時も同じ。デバッグしてすぐに問題点が見つかるのであれば直せば良いが、なかなかデバッグしてもうまく動かないときは、思い切って変更を切り捨てて、最後にチェックインしたところにまで戻る。特にこれが必要なのが、新しい機能を追加した時に、今まで動いていたものが動かなくなってしまった場合。「なぜ動かなくなったか」を解析している時間と、ゼロからもう一度書き直す時間とどちらが大切なのかを考えると、ゼロから書き直した方が早い場合が多い。これは私の経験だが、動くはずのプログラムが思った通りに動かないときの一番の原因はつまらないケアレスミス。セミコロンの入れそこないだとか、x と y が逆になっていたりとかだ。そんなケアレスミスがなかなか見つからずに煮詰まってしまうことは良くある。そんなときは、躊躇せずに変更を全部捨て、最後にチェックインしたところまで戻って、ゼロから書き直す。
これを読んでも分かるように、私のプログラミング・スタイルには、ソースコードのバージョン管理をしてくれるシステムが必須。たとえ一人でプログラムを書いていてもこれは同じ。そして、イメージとしては、階段を一段一段踏みしめながら登るように、チェックインのたびにテストを繰り返しながら、丁寧に丁寧に一段づつ仕事を積み重ねて行く。積み上げかけた段がうまく形にならなければ、一度その段は完全に取り除き、再びゼロから新しい段を作り直す。ただし、一度作った段を出来るだけ確固としたものにするために、各段ごとのテストは怠らない。「何となく動いている段」「ふにゃふにゃしている段」の上に次の段は作れない。そして、「今日は七段登る」と決めたらよほどのことがない限り七段登れるまでは家に帰らない。そのかわり、予定よりはやく七段が作れてしまえば、さっさと家に帰る。どうしても煮詰まったら、一度家に帰ってゆっくりと頭を休めて、フレッシュな頭で再度チェレンジする。とにかくマイクロタスク単位での自分のプロダクティビティを最大化するには何をしたら良いかを常に意識して仕事をする。
CVSとWinDiffにはお世話になりっぱなしです。
Posted by: dt | 2007.09.16 at 00:04
私も「ひとりでもバージョン管理」派です。チェックイン前のdiffのチェックは欠かせません。が,まわりはフルファイルでやり取りする人のほうが多いです。
Posted by: すずき | 2007.09.16 at 00:55
割り込み禁止、それが出来るだけでどれほど進捗が改善されることか……。
日本の底辺プログラマは細かいトラブル対応からDM発送まで一手に押しつけられて、割り込み拒否なんか出来やしません。
sigh...
Posted by: ataru | 2007.09.16 at 02:14
私のとっておきのプログラミングスタイル
Upload a file to www.beinspace.com give it a name a and a link to your site
And this information will live for ever in outer space.
Posted by: agmon | 2007.09.16 at 04:15
僕が言おうとしたことをataruさんも言ってますが。。。
>大切なことは、この「割り込み禁止状態」と
>「割り込み可能状態」をはっきりと区別して一日を過ごすこと。
外資系のIT企業のように1人のプログラマにワンルーム与えてたり、そうでなくてもパーティションで区切られたワークスペースでないと無理ですね。
優秀なエンジニアは優秀なワークスペースを得られるが
そうでない大多数のエンジニアは劣悪なワークスペースに
ぶち込まれてるのが現実です。
TODO管理は多くのプログラマでがやっているでしょうが、
参考になりました。
Posted by: HALion | 2007.09.16 at 06:18
>「なぜ動かなくなったか」を解析している時間と、ゼロからもう一度書き直す時間とどちらが大切なのかを考えると、ゼロから書き直した方が早い場合が多い。
この考えは羨ましいですね。私も常々、そう思っています。
私は、自動車業界のシステム開発を担当していますが、この業界では、ゼロからのやり直しよりも、
「なぜ動かなくなったか」を解析し、何が真因かを突き詰めるまで、何時までも時間をかけます。
これは、「失敗した原因がわからないとまた同じ過ちを繰り返す」、というトヨタ理論によります。
とっても面倒で要らないと思うのですが、この業界では、成功した要因も失敗した真因も突き止めるまで
仕事をとめます。この原因を抑えておけば次回の開発ではよりやり直し業務が減り、効率が上がるらしいですが。
Posted by: rei-rei | 2007.09.16 at 07:52
>これは、「失敗した原因がわからないとまた同じ過ちを繰り返す」、というトヨタ理論によります。
私も製造業関係のシステムを担当しています。
製造業では「生産性は誰でも一緒」が前提だからですね。
失敗の原因を追究し、仕組みとして落とし込んで、繰り返さない。
それが問題解決の手順です。
しかしプログラミングではよく言われるように腕による生産性の格差が大きいです。
同じ手順が当てはまるのかはわかりませんね。
Posted by: HiroA | 2007.09.17 at 07:31
>割り込み禁止状態
これは難しい!
Posted by: hg | 2007.09.17 at 18:29
『「たぶん動くだろうけど、バグがあったらテスターが見つけてくれるからいいや」という考えでチェックインするのは犯罪行為』=自殺行為(笑)
テストは重要だと思う。自分の仕事に対して自信も持てる。
また、誰かのコメントにある、「動かない理由を調べずにゼロから書き直す」という考えは私は好まない。
Posted by: masa | 2007.09.17 at 21:47
皆さん色々意見を述べておられるようですが・・・。
無理・うらやましい・好まないといったコメントが多いのはいかがなものかと。確かにそれも現実なのかもしれませんが、改善することは出来ます。
それよりも重要なのは意識ではないでしょうか。割り込み禁止~は物理的なものではなく集中力の問題ですし、ゼロからもう一度~もつまらないミスで時間を浪費しないということかと。
前者に関して。「細かい作業や環境といったやむを得ない事情がある」という意見があるかもしれませんが、細かい作業ごとに割り込み禁止のマイクロタスク化するなどは出来ます。大事なのは仕事を曖昧にしない(簡単な内容であれ)ということに尽きます。
後者に関して。失敗というものの捉え方の問題で、satoshiさんがおっしゃっているのは「失敗というものに囚われすぎないように」という意味だと思います。失敗の原因を調べることは確かに重要なのですが、それはあくまで手段であって目的は仕事を完遂することです。その目的を果たすために一度戻って脳をリフレッシュしてからやり直すことが重要と述べているのだと思います。
(と言うよりも重大なミスであればゼロから書き直そうが再び発生します。そうなれば、重大なミスに絞ってそのバグ潰しに全力を注ぐことが出来ます。)
スタイルは自らの意識レベルが顕れたものに過ぎない、ということでは無いかと私は考えます。
駄文失礼しました。
Posted by: hide | 2007.09.28 at 15:26