さいきん、これ
どうしてプログラマに・・・プログラムが書けないのか?
http://www.aoky.net/articles/jeff_atwood/why_cant_programmers_program.htm
がはやっているようだ。
この文を読んで。。
あー、この書いた人がプロジェクトマネージャーになったら、開発はデスマーチ、プログラマは地獄だろうなと思った。
どうしてか。。を書く前に、まず、ここで話題になっている話を1つ
(以下斜体は上記サイトより引用)
ここでは、「Fizz-Buzz問題」というのを取り上げている。
それは、
1から100までの数をプリントするプログラムを書け。ただし3の倍数のときは数の代わりに「Fizz」と、5の倍数のときは「Buzz」とプリントし、3と5両方の倍数の場合には「FizzBuzz」とプリントすること。
というものです。
で、それについて、
ちゃんとしたプログラマであれば、これを実行するプログラムを2分とかからずに紙に書き出せるはずだ。怖い事実を聞きたい? コンピュータサイエンス学科卒業生の過半数にはそれができないのだ。自称上級プログラマが答えを書くのに10-15分もかかっているのを見たこともある。
うん、この人は、プログラマでよかった。。
この人がSEかマネージャーになったら、このプロジェクトはデスマーチになるだろう。
もし、上級プログラマが10分かかっていて、
コンピュータサイエンス学科卒業生の過半数ができないのに、
自分が2分でできると思っていたら、
それは、世間が間違ってるんじゃなくって、自分の考えが間違っている。
そう考えないと、”おじさんの運動会”になってしまう。
おじさんが、子供の運動会に参加することがある。
そうすると、おじさんはなぜかこける・・・
なぜ、こけるのか。。
自分は走れるとおもっているけど、体はそう動かない。
なので、こけるのだ。
それと同じ。自分は2分でできると思って、計画を立てておいて、
2分でできない人が続出した場合、プロジェクトはこけてしまう。
でも、2分でできると思い続けている限り、
なぜ10分かかるのかの理由がわからないから、
永遠と転び続ける。。。
デスマーチの多くの原因は、この、勘違いによることがおおい。
プログラム能力の差異は、実は教育方法があるから、埋められるのだ。。
(その教育方法を、大学やプログラマが知らないということがあるのだが。。)
さて、このケースでは、なぜ、2分でできると考え、自称上級プログラマが10分かかるのか、考えて見ましょう。
まず、2分でできると考えた人は、こういうプログラムを書くと思う。
public class testpro2 { public static void main(String[] args) { for(int i = 1 ; i <=100 ; i ++ ) { if ( (i % 3 == 0 ) && ( i % 5 == 0 ) ) { System.out.println("FizzBuzz"); } else if ( i % 5 == 0 ) { System.out.println("Buzz"); } else if ( i % 3 == 0 ) { System.out.println("Fizz"); } else { System.out.println(i); } } } } |
(上記< > ¥は、本当は半角です)
ここで、悩んだり、できなくなったりする理由は、この書き方が、仕様書とはちがっていることだ。
仕様書は、あくまでも
1.3の倍数かどうか調べよ!
2.5の倍数かどうか調べよ!
3.3と5の倍数だったら。。
ときている(たぶん、意図的にこの順番にしている)。
ここで、testpro2のif文を、この仕様書の順番で、
if ( i % 3 == 0 )
からはじめてしまうと、3と5の倍数のときも、これにひっかかって
Fizzと印刷してしまう。
かといって、elseifをつかわないで、ifでかいて
if ( i % 3 == 0 ) { System.out.print("Fizz"); } if ( i % 5 == 0 ) { System.out.print("Buzz"); } |
と書くと、今度は15の倍数のときの条件を、
仕様書には書かれているのに、プログラム上は書かない上に、
なにも出力しない場合、数字を書き出すためのフラグを持たないといけない。
もちろん、仕様書を無視し、同じ結果が出ればいいと考えるかもしれないが、
これをやり始めると、デスマーチになるのだ。。
修正で想定外のことが起こる危険がある。
たとえば、3と4の倍数の場合。。というのを仕様書に追加したとしたら、
それは(上記testpro2中でしめした)3と5の倍数の上に書くのか、
下に書くのか、このとき、どちらにかくかで、60で違いが出てくるのだが、
そーいう複合条件における、仕様のもれが、まさにデスマーチにつながってくる。
だからこそ、仕様書と、プログラムの条件判断は、あわせたいのだ。
で、この問題は、こうやって考えると(このケースでは)解決する。
(たぶん、この方法で解決するように条件が並べてあるように見える)
王道は、崩すべきではないのだ。
条件判断は、まず、
1.判断する値を全部集める=>今回はない
ここで、状態によって処理を換える場合は
2.わたしはだーれ?と聞き、状態を決定する
3.状態=>処理に変換が必要なら変換する
4.処理をディスパッチする
という方法をとる。さっき書いた決定表のketteiCntl.javaにおいても
そのようになっていて、「条件判定」が2にあたり、「実行」が4にあたる。
この間に、3に相当する「実行条件の選択」というのが入っている。
今回の処理の場合、3が必要ない(起動する処理は1つ、「印刷する」なので)
したがって、それを考えると、こういうプログラムになる。
/** * * Fizz-Buzz問題 * */ public class testpro1 { /* * 実行部分 */ public static void main(String[] args) { // メイン処理(100までループ) for(int i = 1 ; i <= 100 ; i++) |
(上記< > ¥は、本当は半角です)
こうすれば、条件変更があっても、「条件判断部分」が仕様書と一致しているので、仕様変更があったときでも、「仕様書と同じ順番でやってます。」といいきれる。
同じ順番でやっている以上、仕様書どおりの順番で書いて、おかしくなっても、(さっきの例だと、3と4の倍数を、3の倍数の前に入れようが、3と5の倍数の後に入れようが、仕様書と同じ順番でコーディングできる。その結果、おかしくなったとしても)「いやー、あんたが書いたとおりやっておかしくなったんだから、そりゃーあんたが悪い」とは、口が裂けてもいえないけど、仕様の書き手に対して、どうしておかしくなったかは伝わる。
そうすれば、仕様書の書き手とプログラムが一致するので、書き手があらかじめ順番を考えることができる。さらに、仕様書とプログラムが一致すると、自動生成の可能性も出てくる。ワーカーにも説明がつく。
ワーカーに説明できる=プログラムが書ける必要性はないのだ。
こちらの説明どおりに書いてくれれば、いいわけだし、自動生成にもちこめば、まさにかける必要はない。
実際にプログラムを書くのはウィリアムのいたずら、後の人は、Excelシートをがんばって保守っていう作業もある。これで、1000個のソースとかを自動生成して管理する(保守要員1名で)という話もある。たぶん、保守してる人は、プログラムかけないと思う。でもシステムは回っているのだ。これでOK!
ところが、プログラマ側で勝手に仕様書と書き方を変えてしまうと、ちとこまる。
仕様書の書き手は疑心暗鬼になってくるし、実際、論理が破綻してしまうこともある。
保守も???ってなってくる
プログラマの技量によるところ大になり、自動生成もできない
(だから、1000個のプログラムを1人で直す。。。は無理なので、何人かに分けてとなり、人も増える)。。。
あちゃー、デスマーチなのですよ。。。
でも、こーいう事態が結構あるんだけどね。。
ちなみに、じゃあ、条件がすべて、上記のような体系でかけるかというとそうではない。
まず、条件には、単純なIF文と、状態判定をするような複雑なケースがあり、複雑なケースにおいては、オプション型の、どんどんやることを追加していくものと、状態型のある1つの状態のとき、やることはこれ!という方法がある(今回は状態型を採用した)。
そして状態型は、決定表に持ち込む方法と命題に持ち込む方法などがある(今回は命題に持ち込む方法を採用した)、詳しい話は、「開発の初めから順番に書いていってみる」で、決定表の話が終わった次に、条件判定の体系化というようなかんじの話で行う予定ですけど(そこで、どうして今回の条件の並べ方が、意図的に感じられたかは書きます)。。。
今回は、そのなかの1つをつかって、ばちんとうまく言ったって言う話。
だけど、これ、多分話をよんでしまえば、
なーんだ!
でおわってしまう話なんで。。あんまり、重要なことではない。
(大学とかで、教えてあげればいいのに。。昔は、会社で教わったのね)
で、実際、eclipseを立ち上げてから、testpro1をコーディングしてテストし、コメントを入れるまでで、だいたい10分かかった。
つまり、上級の人は、
1.はじめに2分でおもいついている
2.でも、「いやまてよ、仕様変更があったら?」と考え直し
3.こっちの方法のほうが、きれいだよね!と考えを変えて
4.それをコメント入りできれいにコーディングしている
だから、10分かかってるってことだとおもう。
15分の理由、つまりあと5分でなにをしているかというと、いろんな言語をやっている人の場合、倍数のあまり0は、%なのか、mod関数なのかが気に係り、ネットでチェックしてるんだと思う。上級者になるほど、そーいうところは確認するような気がする。
(英語、できるやつほど辞書で確認をとるっていうやつ)
なので、この5分は別に。。指摘するほどのことでもない。
むしろ、重要なのは、思いついたプログラムをすぐに書くんじゃなくって、
一回、考えをためてから、書いていることだ。
この「考えをためて、冷静になって考える」ことをしないと、ぐちゃぐちゃな場当たり的なプログラムになってくる。
この差のほうが、むしろ重要だと思う。
あ、このほかにも、さっきの「どうしてプログラマに・・・プログラムが書けないのか?」「連結リストを実装」あー、そーねそーね、CのポインタにおけるJavaでの実装の問題、デザインパターンのおはなしとか、あのへんねえ。。。とか「実際的な問題を解くのに再帰が使える」あーそーねそーねー、再帰の実装の問題ねえ。。
と話したいことがみつかっちゃったんだけど、いい加減長くなりすぎたので、今回はここまで(シリーズ化しちゃう?)