Home日記コラム書評HintsLinks自己紹介
 

フィンローダのあっぱれご意見番 第165回「職人はよいものを速く作る」

← 一つ前 | 「フィンローダのあっぱれご意見番」一覧 | 次のをみる →

寿司職人の名人が寿司を握ると、 米粒の数が毎回同じになるという。 テレビの検証番組を見たような気もするが、定かではない。 想像するに、 寿司米を掴んで握る、掴んで握る、…という作業を日々延々と繰り返し続けるうちに、 ベストの分量の米粒を選択する精度がどんどん高くなって、 極めた人は誤差が数粒になる、 ということだろう。

 

※ おそらくこの技を達成するためには一定の品質の寿司米も必要だ。

このような達人の技は、さまざまな分野に例がある。 大工の棟梁ともなれば、釘を何本打たせても、きっちり垂直に打つ。 もちろん、斜めに打つべき所は、限りなく狙い通りに斜めに打ち込む。 素人のように指を叩いてしまうようなことはない。 と思うのだが、これは確かめたわけではないから、 弘法も筆の誤りということがあるかもしれない。 弘法といえば、 字の美しい人が字を書くと、 毎回同じように精度の高い字を書くことができるのだが、 これも一つの職人芸なのだろう。

この種の正確さは、熟練したスポーツ選手にもみられる。 水泳の選手が同じ距離を泳ぐときのストローク数は、毎回同じだという。 もちろん、さらにそれを基準にして、今日は1回増やしてみようとか、 そういう作戦を立てることもできるとか。 そう考えてみると、走り幅跳びの場合、 オリンピックのような世界トップレベルの戦いでも、 助走でファウルになる選手が続出する。 つまり、助走というのは極めて難しい技術なのだろう。 ファウル寸前の限界のところで戦っているから、 必然的にファウルも増える、というような考え方もありそうだ。

§

この種の熟練者の技術には、 最適な数量を経験によって体で覚える、 という共通の要素がある。 面白いのは、その技術を実践するときの時間だ。 寿司名人が握る寿司と、素人が握る寿司。 どちらが早くできるか。 達筆といわれる人と字が下手な人とでは、どちらが早く字を書けるか。 長時間かけてクオリティが高いモノを作るわけではない。 むしろ、素人よりも短時間で完成させているのだ。

品質が高いモノを早く完成できる秘密は何か。 これは、積み木のモデルで説明することができる。

品質の異なる2種類の積み木がある。 一方の積み木は、いいかげんに切ってある。 少し斜めになっているし、大きさが不ぞろいだ。 これを適当に選んだ地面の上で積んでゆく。 規模が大きくなるにつれて、作業は劇的に難しくなり、 ある限界を超えることはできないということが想像できるだろう。

これに対して、 高い精度で直方体にカットされた積み木を、 完全に水平な床の上に積み上げてみる。 結果は想像の通りで、 理由を説明するまでもないはずだ。 各部品の品質がよければ、より大きな構造物を構築する作業は、 格段に楽だし、大規模な作品も可能になる。

では、その「品質の高い積み木」や「完全に水平な床」はどうすれば手に入るか。 あるいは、どうすれば選別できるか。 もし自分で作るとすれば、それを作るには時間がかかるのではないか。 いや、それらを短時間で解決するための技能が職人芸なのだ。 それをモノにするためには、長い修行が必要だが、 逆に考えると、 短時間で正確なモノを作る技術は、 ある種の反復練習によって身に付くわけである。

§

ソフトウェアの品質は高い方がいいに決まっている。 というと当たり前のような話だが、 いやそうでもない、という人もいるのだ。 理由を聞くと、 品質よりも、納期を優先すべきだという主張らしい。 つまり、短期間で作れるなら品質は後回しでも構わないという話らしい。

では、 品質の高いソフトウェアを作るには、 長い時間が必要なのか? 他の分野の職人が短期間で高品質のモノを作ることを既に紹介した。 ソフトウェアの世界にも職人がいる。 プロとアマチュアのプログラマーの違いは何か、 というのは、昔、プログラマーズフォーラムでよく話題になったテーマの一つだ。 「プロは、高い品質のモノを、短期間で作ることができる」 というのは、その答えの一つになるだろう。

ソフトウェアにも職人芸の法則が当てはまる。 理由は単純だ。 修行をし、経験を積んだプログラマーは、 どのようにコードを配置して、、 どのような分量でモジュールやメソッドを分け、 どのような順番で並べることで、 アルゴリズムの無駄を避け、 保守性を高めることができ、 最適なコードを書けるのか、 経験的に知っているのだ。 その判断を瞬時に行えるようになったとき、 そのプログラマーは職人として完成する。

  

これに対して、 経験の少ないプログラマーは、適切な数量を瞬時に判断することができない。 反復的にコードを書くという経験を積まないと、 この種の判断は身に付かないのだ。 未熟なプログラマーは、直感的にこの種の判断ができないから、 基本的に、最初からよいプログラムを書くことができない。 書けるのは、あまりよくないプログラムである。 時間をかけてリファクタリングやデバッグをすれば、 よいプログラムに近づけることは可能かもしれないが、 個々の積み木が不揃いのままだと、 プログラム全体の品質を、 一定以上にすることは難しい。

 

※ 積み木のモデルでもう一つ重要なのは、 熟練者は経験によって、 どのような順序でどのように積めばうまくいく、 ということを知っているということ。

もちろん、熟練者といえども、 必要最低限の時間がなければ、 ソフトウェアを作ることはできない。 しかし、その最低限の時間というのは、 未熟なプログラマーが最低の品質のプログラムを作るよりは短いし、 出来上がったプログラムの品質は極めて高くなるのだ。

§

  

リファクタリングは必要だし、 それで品質が向上することは多い。 しかし、リファクタリングがなぜ必要なのか考えてみると、 ふと疑問がわいてくる。 なぜ最初からリファクタリングしなくても済むように書けないのだろうか? あるいは、最初から最適な状態で書くことはできないのか?

 

※ 利ファクタリング: 処理の内容は変更せずに、 プログラムを修正すること。

熟練者といっても、ある種のリファクタリングは、やはり必要だ。 仏像は、まず荒削りをしてから仕上げに入る。 マンガの原稿は、まず下書きをしてからペン入れする。 プログラミングにも、このような手法が応用できるし、 それは一種のリファクタリングだと考えていい。 リファクタリングが不要な完璧なコードを、一発で書くことは難しいのだ。 とはいっても、ある種のリファクタリングは、 熟練すればするほど、不要になってくる。

例えば、リファクタリングで意外と多い作業の一つが、 名前の変更だ。 変に衝突しない限り、 変数やメソッドの名前を変えても、 全体の動作には全く影響しない場合が殆どである。 しかし、適切な名前は、 劇的にリーダビリティを向上させる効果があるし、 その副作用として、 全体の構造の見通しをよくし、 結果的にバグも少なく、性能をよくすることも簡単になるわけだ。

この種のリファクタリングは、 プログラミングに慣れてくると、あまり行わずに済むようになる。 どんな名前を付ければいいか、経験で身についているからだ。

  

もう一つリファクタリングで多い作業は、 処理の囲い込みというか、メソッドの中にある一連の処理を別メソッドにする、 あるいは逆に、メソッドとして分離されているものを、 メソッド内に埋め込む、というような構造の変更である。 これは、思いがけずメソッドが長くなってしまったときに、 30秒ルールを守るために行ったり、 あるいは、あまりにメソッドの数が増えすぎて、 かえって全体の流れが分かりにくくなっている場合に行われる。

 

※ 30秒ルール: Java のメソッドでよく適用されるルール。 メソッドのソースは、 初めてみた人が30秒で理解できるように書かなければならない。 30秒で理解できない場合は、バグとみなされて、書き直しの対象となる。 違うかも。

これも熟練すればあまり必要がなくなるリファクタリングである。 ある処理を作るときに、 1つのメソッドで書くと300行必要だと最初にイメージできたら、 30行程度のメソッド10個に分けることを想定して書き始めるのである。 書いているうちに思いがけず300行になってしまった、 というようなことは ソフトウェアの熟練者には有り得ない。 この処理はこの程度で書ける、というような見積もりが、 経験により判断できるからだ。

もしプログラマーが本当に未熟なら、 そもそも300行の分かりにくい複雑なメソッドを見ても、 リファクタリングしないような気がする。

§

積み木の話では、テキトーな地面と水平な床、という極端な例を想定した。 砂上の楼閣という言葉もあるように、 土台がよくなければ、上にモノをうまく積むことはできない。 ソフトウェアでいえば、 それを動かすためのOSとか、フレームワーク、 ライブラリなどの下位のモノがしっかりしていないと、 上に大きなものを乗せることが難しくなる。

「安定している」という、あまり面白くない言葉がある。 実は、殆どのソフトウェアは非常に安定しているのだ。 即ち、バグがあれば、条件が成立したときに確実に障害が発生する。 「メモリが足りなくなったら不安定になる」という話はよく聞くし、 経験もあるかもしれない。 大抵、この現象は、 本当にメモリが足りなくなったときに確実に使えなくなる、 というものである。 つまり、安定しておかしな状態なのだ。 「本当にメモリが足りない」という条件は、 偶然成立することが多いために、 ユーザーが見ると、ランダムに動かなくなるように感じてしまうだけだ。

  

実は熟練者であれば、 ある程度は不安定な土台でも、それなりのモノを作ることは可能である。 もちろん、可能なら土台をしっかり選択したいのだが、 現実にはそれが許されないような状況もしばしばあるのだ。 熟練したプログラマーは、 システムコールや API の、どこあたりが安定していて、 どこを使うと破綻するか、ということを経験的に知っている。 さらに、この API はなぜ不安定なのか、ということも知っていたりする。 どうすれば現象を回避できるとか、 どちらかというと技法というよりは薀蓄話みたいなノウハウも、 経験を積めば自然に身についてしまうものだ。

 

※ まあナニとは言いませんが、 ある程度慣れてきたら「このAPIのリファレンスは間違っている」とか、 「ここはマニュアルに書いてない初期化をしないと使えない」 みたいな秘伝の技がわんさかと身に付いてくると。

§

今から十数年前に、ソフトウェア危機という言葉が流行した。 10年後、20年後に、ソフトウェア技術者が何十万人とか何百万人という規模で不足する、 というのだ。 現にその時代になって、どうだろうか。 ソフトウェアを作れる人は大勢いても、技術者が少ないような気がするのは、 気のせいだろうか。

  

(C MAGAZINE 2006年3月号掲載)
内容は雑誌に掲載されたものと異なることがあります。

修正情報:
2006-03-11 裏ページに転載。

(C) Phinloda 2006 All rights reserved.