読者です 読者をやめる 読者になる 読者になる

$shibayu36->blog;

株式会社はてなでエンジニアをしています。プログラミングや読書のことなどについて書いています。

コードコンプリートを再読した

 以前職業プログラマーなら必ず読むべき「Code Complete」 - $shibayu36->blog;補足 - 職業プログラマーなら必ず読むべき「Code Complete」 - $shibayu36->blog;で紹介したコードコンプリートを再読した。

Code Complete 第2版 上 完全なプログラミングを目指して

Code Complete 第2版 上 完全なプログラミングを目指して

Code Complete 第2版 下 完全なプログラミングを目指して

Code Complete 第2版 下 完全なプログラミングを目指して

 一年前はどちらかというと、コードのスタイルの話とか、条件をどうやって綺麗に書くのかとか、コメントはどう書くのかということを学びたくて読んだけど、今回はクラス設計をどうしていくべきかとか、チームでのエンジニアリングをどうしたら良いかとかを中心に読んでいった。

 やっぱり学びたいと思っている内容が違うとそこそこ目に入ってくる項目も違うようで、前とは違う内容も勉強することが出来たように感じた。印象に残ったことを適当に書いてく。

欠陥の修正にかかるコスト

 3章くらいに、欠陥の侵入した時期とそれを発見した時期による欠陥修正の平均的な修正コストという話が書いてあってこのへんは面白かった。要求時点で欠陥が入って要求時点でそれが見つかった時の修正コストを1とすると、要求時点で欠陥が入ってそれがシステムテストの段階で見つかった時の修正コストは10に跳ね上がるとか書いてある。

 このへん最近話題のPull Requestでいろいろ指摘しては遅過ぎで設計段階で議論すべきっていう話にも通ずるところがあると思う。Pull Requestで議論を始めるとシステムテストまで終わった状態とかんがえることができるから、もし要求段階でバグが入ったら修正が10かかる。でも要求の段階でレビューを行って修正が出来てたら1で済む。早い段階で相談するのは修正コスト的にも重要ということが分かる。

 実際Pull Requestまで来てしまって根本的な設計が間違っているよねって話になると、大体修正コストが高すぎて修正しないという自体が発生するので、なんとかして早めに調整する必要があると思った。

一度に対処しなければならない複雑さを最小限に

 コードコンプリートでずっと言っているのはやっぱりこれだと思った。どんな方法も一度に対処する複雑さを減らすために行う。ルーチンへの良い名前付けも、条件を分かりやすく書くことも、情報を隠蔽することも、クラスを分割することも、これのために行う。

 前回はルーチンの名前付けとか、条件の良い付け方とかその辺に目がいっていたけど、今回はもうちょっとクラス設計よりの方に目がいった。

「凝った」設計を避ける

 まず基本的には「凝った」設計を避ける。プログラマとしていろいろやっているとなんとなく最新の技術を使ってかっこいいものを作ったり、黒魔術を使ってかっこいいことをしてしまいがちなんだけど、それだと大体理解しづらいものが出来てしまう。ある目的を達成するために一番単純な設計を選択したほうが良い。

 またあとで便利かもと言って、今は問題にならないけどさきのことを考えたコードを作成するとだいたい失敗する。さきのことを考えたコードは、考えているのが人間なので大体推測に失敗する。逆にその設計のために変更しにくいプログラムになってしまう。仕事でプログラムを書いていると大体こういうことを一度は経験している気がする。

 最近はある程度許容できる問題はあまり実装しすぎないようにしている。全ての入力に完全に対応できるコードは確かにすごいけど、大体レアケースへの対処ばかりになってしまってコード自体はわかりにくくなっていく。そのため逆にバグを発生させやすいコードになってしまったりする気がする。

情報隠蔽

 一度に考える複雑さを減らすため、情報を隠ぺいする必要がある。

 情報隠蔽の「秘密」の種類については以下のようなことが書いてあった。なるほどという感じ。

情報隠蔽の「秘密」は、大きく2種類に分類される。
・複雑さを隠蔽して、特に必要なければ考えずに済むようにする。
・変更の源を隠蔽して、変更が発生したときに、その影響を1ヶ所にとどめる。

 あと、この部分は「何を隠ぺいする必要があるか」という問いかけは、すべてのレベルで良い設計を後押しすると書いてあった。クラス設計とかいろいろ難しいけど、何を隠ぺいするかと問いかけて考えるというのは良い習慣かもしれない。

プロジェクトのそれぞれの作業は二人で分担

 28章くらいに良いコーディングを奨励するテクニックとして、プロジェクトのそれぞれの作業は2人で分担するということが書いてあった。この辺なるほどと思う部分が多い。

 二人である物事に取り組むと、大体会話をしている最中に設計が良くなっていくことが多い印象がある。議論にならなくても良いことも多くて、話しかけるためだけのぬいぐるみとしてだけでも良いこともある。「この部分よくわかんないんだよねー、これがこうなってこうしたいんだけど、、、あ、説明してたらなんかまとまってきたこうすればいいんだ」みたいなことがよくある。でもこういう設計は大体一人で黙々とやってると迷走することが多い。

 こういうこともあるので、ちょっと大きめな新機能開発とかは、最低でもペアで取り組ませるほうが良さそうだなと思った。もちろん実際にプログラムを書くメインプログラマーはこの人と決めてもいいとは思う。でも最初の設計は二人で会話したりしながら決めると良さそう。

コードレビューの二次的効果

以下の様なことが書いてあってなるほどと思った。

人は自分のコードがレビューされることを知ると、コードを入念にチェックするようになるという二次的な効果もある。

ペアプログラミングの有効利用

 21章くらいにペアプログラミングを安易に使用しないって書いてあって面白かった。

最も複雑なコードにペアプログラミングを使っていたグループは、15分間ホワイトボードで詳細な設計を確認してから、1人でプログラミングを行う方法が合理的であることに気づいた。

と書かれていたり

ペアプログラミングを試してみた組織のほとんどは、最終的に、作業全体ではなく作業の一部にペアプログラミングを使用する方向に落ち着く

とか書かれている。

 実際最近チームでも同じようなことを話していて、単なる作業だとペアプロはただ速度が落ちるだけだよねとか、逆にちょっとモチベーションが低いタスクのドライブにはなるよねとか、そういう話をしてた。

まとめ

 なんか印象に残ったところを適当に書きまくっていったら結構分かりにくい感じになった。コードコンプリートだいぶ昔の本なのに、今の開発にもいろんな方向で役立っていてすごいと思った。

 コードコンプリートすごい良い本で読むべきと思ってるけど、とにかく分厚いので躊躇されがち。コードレビュー - hitode909の日記でも言及されていたけど、とりあえずリーダブルコード読んだほうが手っ取り早いとは思う。

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)