高慢と偏見(10) 夏への扉
「S系部品納入時チェック機能」の仕様がまとまったのは、それから数日後のことだった。
S系部品とは、その名のとおりコードの先頭がSで始まる部品群のことで、部品全体の5%未満が該当するらしい。K自動車が過去に傘下に入れたメーカーが使っていたコード体系がそのまま使用されているため、他の部品とはロジックが共有しづらい。他の機能との関連性も低いので、このような、言ってみれば練習問題にはちょうどいいのかもしれない。
私は、平良さんが、なぜこの「証明」を提案したのかをずっと考えていたが、いまだに見当もつかなかった。そもそも「勝敗」の判定方法自体が曖昧なままなのも、平良さんらしくない。作成期間はともかく、機能の出来具合なんてどのように判定するつもりなんだろうか。
両チームに機能説明書が渡されたのは月曜日の午後。画面が5つという、比較的単純な構成だった。
私たちBチーム、というか若槻さんと私は、早速打ち合わせに入った。5人で画面5つだから、1人あたり1画面としたいところだったが、新人くんたちにいきなり渡しても右往左往するだけだということは分かりきっている。だから、私たちは相談して、次のような方針を決めた。
- まず、若槻さんと私が協力して1画面を仕上げる
- 基本のコーディング自体は私が担当する
- 若槻さんは、共通ロジックとして使える機能をできるだけ抽出し、インターフェイスとして定義する
- 最初の画面が完成した時点で、それを基本パターンとして、新人くんたちに教え込む
- 若槻さんは、並行して、共通ロジックの具象クラスを作成する
- ある程度、やり方を飲み込んでもらった時点で、残りの4本を一気に仕上げる
設計を始めてみると、5画面のうち4画面は比較的似ていることが分かった。似ているということは、共通ロジックとして切り出せる部分が多いということになる。若槻さんの腕の見せ所だ。
――これなら、ほとんど部品を組み合わせる感覚で作れるかも。
若槻さんは、ほぼ半日でインターフェイスの作成を終え、それぞれの具象クラスの実装に入った。
私は並行して最初の画面の基本部分を作ったあと、ロジックの実装に移った。若槻さんの作成したインターフェイスは、過不足なく定義されていたので、いくつか引数を修正してもらうだけですんだ。プロの――それも優秀な――仕事はいつ見ても気持ちがいい。
サンプルとなる画面は、1日未満でできた。項目やボタンの微調整はどうせ発生するに決まっているので、それほど作り込んではいない。私は早速、新人くんたちを集めてコードを見せながら説明を行った。
最初の説明が終わったとき、新人くんたちの頭の中には「?」がたくさん生まれたようだった。彼らが口にした数々の質問から、その混乱の度合いが想像できた。
「どうしてインターフェイスを宣言するだけでいいんですか?」
「インスタンスは誰が作成してくれるんですか?」
「なんでファクトリーというものが必要なんですか?」
「どうしてこんなにたくさんメソッドを作らなければいけないんですか?」
などなど。
オブジェクト指向の基礎的な知識はもちろんだが、やはり彼らには定石とも言うべき経験が欠けていた。三浦マネージャの教育方針は、徹底して「動けばいい」というものだったらしいから。例えば、あるマスタからの結果セットをMapにセットするロジック。
List<XxxDto> xxxList = xxxListGetter.select(selectKey);
Map<String, String> xxxNameMap = new HashMap<String, String>(xxxList.size());
for(XxxDto xxx : xxxList) {
xxxNameMap.put(xxx.key, xxx.name);
}
このコーディングについて、1人が質問してきた。
「このHashMap の宣言で、初期サイズを指定していますが、これがなくてもコンパイルエラーにはならないですよね?」
「ならないでしょうね」10才近く年下だとはいえ、私にとってはお客様企業の社員様だから、いちおう丁寧語だ。
「三浦マネージャがおっしゃってましたが、これぐらいはコンパイラが最適化してくれるって」
「くれるでしょうね」
「それなら不要なコーディングということになりませんか?」
「ならないでしょうね」
「あの……」
――やれやれ。
時間もないし、いじめるのはこれぐらいにしておいてやるか。
「つまりですね、この xxxList.size() は、初期サイズを決定する他に、このMapの大きさはxxxListと同じだよ、と説明する役目もあるということなんです」
エウレカ! と叫びこそしなかったが、その新人くんの瞳に理解の色が広がった。
「後から違う人がコードを読むとき、意味が分かりやすいですよね?」
「分かりました!」
――素直でいい子じゃん。誰かとは大違いだね。
私は心の中で、その新人くんの頭をなでなでしてあげた。ごほうびにキャンディーでもあげたいぐらいだ。
若槻さんがやっている共通ロジックの切り出しについても、最初は理由が分からないらしかった。なにしろ、今までは似たような処理は、コピペで量産していたのだから。寡黙な若槻さんには質問しづらいらしく、新人くんたちは、またもや私に問いをぶつけてきた。
「どうしてコピーして作ってはいけないんでしょうか?」
「どうしてコピーで作っていいと思いますか?」私は聞き返した。
「ええと……楽だから?」新人くんは自信なさそうに答えた。
「確かに短期的には楽ですけどね。じゃあ、もし、100カ所で似たような処理をしてたとしますね。そのロジックに変更が入ったとしたらどうします? 100カ所、手で修正しますか?」
「Eclipse の置換機能で一括で置き換えてしまえばいいと思いますけど」
――ああ、きっと今までそうやってきたのね。
私は聞こえないようにため息をつくと、あまりにも当たり前な説明をした。
「その100カ所が完全に同じだったらいいですけどね。でも、誰かが微妙にコメントを追加してたり、ある画面用に修正加えてたりしたら、完全一致しなくなりますよね」
「……」
「1カ所でしか使わないロジックなら、その画面ロジックの中で収めておいてもいいですよ。でも、2カ所で使うことになったら、共通ロジックとして切り出しておくことをお勧めしますね。2カ所で使ったってことは、ひょっとして3カ所で使う可能性だってあるわけですから」
「なるほど!」またもや理解した表情。
またあるときは、こんな質問が来た。
「あのお、このインターフェイスですけど、同じ名前のメソッドが2つあるんですけど……間違いじゃないですか?」
List<XxxDto> select(String key);
List<XxxDto> select(String key, Date enabledDate);
私は心の中で舌打ちした。
――あのオヤジは、オーバーロードも教えてないのか。
「コンパイル通ってますよね。これは間違いじゃなくて、オーバーロードという仕組みです」
私は簡単にオーバーロードについて説明したが、新人くんには、今ひとつ利点が伝わらなかったようだ。
「でも、違うメソッド名を付ける方が簡単だと思うんですけど」
「はい、確かにその方が好ましい場合もありますね。でもですね、例えば10種類の違う名前のメソッドがあったとして、10個それぞれに端的に内容を表す名前を付けるのは結構大変だと思いません?」
「はあ……確かに」
「このインターフェイスなら、selectってメソッド名を使うことさえ分かっていればいいでしょう。もちろん、JavaDocにそれぞれのメソッドの引数の説明が適切に記述されているということが前提ですけどね」
「ああ、なるほどなるほど!」
こんな調子で、最初の2日は過ぎていった。
私がうっかりオーバーライドを説明してしまったために、しばらくはオーバーロードとの区別を付けるのが大変だったり、変数の宣言にプリフィックスを付けようとするのをやめさせるのに苦労したりと、新人くんたちも私も、混乱の極みだった。
だけど、もともとの素材がいいのと、若さゆえの柔軟性も合わさって、新人くんたちのコーディングは急速にまともになってきつつあった。若槻さんが次々とコミットしてくるインターフェイスと具象クラスがいいお手本となり、プログラミングのおもしろさが分かってきたようだ。
新人くんたちは、ある可能性へ通じる扉を、ほんの少しだけかもしれないけど開き、その向こうを好奇心いっぱいにのぞき込んでいる。プログラミングが退屈な単純労働ではなく、高度な知識を必要とする知的活動だということに初めて気付いて、嬉しいことに、それにハマりつつある。私が指示もしないのにJDKのAPIドキュメントを熟読していたり、IteratorパターンやSingletonパターンを調べては、必要もないのに適用しようとしてみたり。
まるで新しいおもちゃを与えられ、それを使ってみたくて仕方がない子供のようだ。見ていて、つい微笑んでしまう。
――私にもこういうころがあったのよねえ。
ときには、
「コンストラクタって何? おいしいの?」
というたぐいの質問をしてくることもあったが、それはご愛敬というもの。最初から完ぺきを望んでも仕方がない。
私たちBチームが、5つの画面を完成させたのは、着手後、5日目のことだった。
Aチームは、1日半遅れて、完成を宣言した。レビューは次の日の午前中に行われた。
(続く)
この物語はフィクションです。実在する団体名、個人とは一切関係ありません。また、特定の技術・製品の優位性などを主張するものではありません。
コメント
CMP
今回は、読んでいて久々に「プログラミングの楽しさ」を思い出させてくれた。
この後はぐずぐずな展開が待っているだけに、一服の清涼剤とはベストですね。
>私が指示もしないのにJDKのAPIドキュメントを熟読していたり、IteratorパターンやSingletonパターンを調べては、必要もないのに適用しようとしてみたり。
実際はここまでかわいい新人さんってあまりいないんだけどね。
そういうかわいいのが居たら、私が責任の取れる範囲内でどんどんいろんなことにチャレンジさせるんだけど。
Buzzsaw
はぅ・・・、ぐぅの音も出ません。
個人的には清涼剤どころか○○剤的にバキバキになってしまうぐらい
スウィートな内容です。
逆に、今までおめぇは誰かに教えるときに、こういうスウィートな教え方してたか?
と問われているようにも感じました。
それで言うと・・・、ちょっと高慢になっていたなぁ。。。
口にこそ出さないけれど、「これぐらい常識っしょ?」みたいな気持ちが
なかったとも言えない・・・。
反省。
プリントアウトして保管させていただきます。
ryu
今年3年目の若造です。
javaでWebアプリをつくっています。
もともとプログラミングは好きでしたが、デザインパターンを勉強したときに、プログラミングの面白さが加速したことを思い出しました。
「オブジェクト指向ってすげーな。このパターン考えたやつすげーな。」
こんなところから仕事に対する面白さや愛着が湧いてくるのかなと思います。
私もプログラミングの面白さを後輩に伝えていきたいものです。
まるま
毎回楽しみに読ませてもらってます。
揚げ足取りみたいで申し訳ないのですが、「オーバーライト→オーバーライド」かと。
文脈ですぐわかりますが、正しく用語を使うのも大事だと思いますので。
通りすがり
> List xxxList = xxxListGetter.select(selectKey);
> Map xxxNameMap = new HashMap(xxxList.size());
> for(XxxDto xxx : xxxList) {
> xxxNameMap.put(xxx.key, xxx.name);
> }
これで size 指定するとわかり易くなるんですか?
あまりその感覚が理解できないです。よければ教えてください。
直後の foreach 構文を見れば一目瞭然って感じが私にはしてしまうのですけども。
foreach の後で xxxNameMap.put で項目追加すれば初期サイズを越えて追加できてしまうのですよね?
それに HashMap の件数を意識しないといけない場面っていまいち想像ができないです。
flatline
直後のfor文がない場合でも、xxxNameMapがどのように使われるかがわかるので、こうなっているんでしょう。
もちろん、for文の後で追加すれば初期サイズ超えてしまいますが、そういう制限を設ける意図ではなく、xxxListのサイズ = xxxNameMapのサイズということを明示的に表現するためだと思います。
通りすがり
コメントありがとうございます。
発言の順序を入れ替えて確認させてください。
> xxxListのサイズ = xxxNameMapのサイズということを明示的に表現する
だけで
> xxxNameMapがどのように使われるかがわかる
という理解でよいのでしょうか?
これは Java プログラマならみんなが分かるということなのでしょうか?
つまり Java のイディオムとしてかなり一般化しているということですか?
# 本題からは外れますが、 HashMap のコンストラクタ引数は「件数」を示すものではないように思えます。
# http://java.sun.com/javase/ja/6/docs/ja/api/java/util/HashMap.html
みなこわけんじ
「みなこ」って誰だ? おれのことか?
通りすがり
# えーとミナコさんが主人公なんですよね。
なるほど。
一見解に過ぎないなら、私は新人君と同じで不要なコーディングという見解なので、私はどうやっても納得できそうにありません。きっとミナコさんを怒らせてしまうんでしょうね。(笑)
「意味が分かりやすい」という主観的な説明や新人を見下した態度に、悪役として描かれているマネージャと同じ姿勢を感じとってしまったので、ちょっと質問してみました。
これら、主人公の理解力や姿勢も含めて、そういう物語ということなのですね。
ありがとうございました。
K.Oumi
いつも面白いなぁと思って読んでいます。
先にこのあとの記事よんじゃった(^^;
1点「ええ~そりゃないよ~っ」て思ったのは、三浦さんが、いかに酷い人だとして、コピペでやらせるっていう感じの人には思えなかったんだけど(そういう設定の人に思っていなかった)、なんていうか、構造化時代はちゃんとやってきてる人って思ってたんですが、今回の雰囲気ですと、それすら違う人に感じた。
単なる動けばOKなオヤジってだけですよね…
そういう設定だったんだろうか…
ってのがちょっと引っかかった。