Hack Your Design!

『達人プログラマー(新装版)』 読んだ

(image)『達人プログラマー(新装版)』 読んだ

きっかけはRebuild.fm

話されている内容としてはomoさんがひたすら巷で良本と名高い『達人プログラマー』をブッタ切るというものだ。omoさんが一時間かけてじっくりディスる対象となる本ということで逆に気になって手に取った本が本書である。

で、どうだったの?

一読した感想としては、たいへんに良本であった。1999年出版された本ということもあり、一部古い記述があるもののそれを差し引いても良い本だった。

本書はざっくり言うと大きく2つの内容が書かれている。

  1. <達人プログラマ>のメンタルモデルの話
  2. 技術的なアプローチ・実装の話

2の部分はさすがに古い本であることもあり今に比べるとかなり時代遅れな印象を受けた。よって本書のそういった箇所は「ふーん」という感じで読み流してしまってもいいだろう1

では本書の良いところはどこだったのかというと1の部分である。古い本であるにかかわらず書いてあることが全然古びていない。むしろ今エンジニア界隈で言われているあんなことやこんなことが「これほどまで昔から言われていたのか!」という驚きとともに感動があった。

本書で紹介されているTipsを僕なりの説明・解説とともに紹介してみよう(それぞれのTipsは本書からの引用)。

Tip 3 いい加減な言い訳よりも対策を用意すること

達人プログラマは御託を並べない。Shut the fuck up and write some code(グタグタ言ってないでコード書け). さっさとバグ・障害に対する対策・ソリューション・再発防止策を練ること。

via. http://stfuawsc.com/

関連Tips

Tip 24 避難するのではなく、問題を修復すること

バグの原因が誰であるかは関係ない。自分自身の問題として向き合うこと。

Tip 4 割れた窓を放置しないこと

まず最初に窓を割らないことが重要。とはいえスピード・納期重視の開発だとどうしても割れた窓を作ってしまう場面もあるだろう。しかしその窓を放置しないこと。放置するとさらに悪い結果を招く。

「建物の窓が壊れているのを放置すると、誰も注意を払っていないという象徴になり、やがて他の窓もまもなく全て壊される」

via. 割れ窓理論 - Wikipedia

Tip 7 品質要求を明確にする

顧客の品質要求を明確にして、「どこまでやるか」を決めること。開発速度と品質はトレードオフの関係にあることを理解すること。多くの場合、3年かかかって完璧なプロダクトを作るより、3ヶ月でそこそこ動くプロダクトが好まれることが多い。

関連Tips

Tip 51 要求は拾い集めるものではなく、掘り起こすものである

最終的な目標は、顧客の要求どおりのものを作るのではなく、ビジネス上の問題を解決するということ。要求の裏に隠れている理由をきちんと把握しておくこと。

via. 顧客が本当に必要だったものとは - ニコニコ大百科

Tip 8 あなたの知識ポートフォリオに対して定期的な投資を行うこと

  • 毎年1つの言語を学習
  • 四半期毎に何らかの技術書を読む
  • 勉強会・ミートアップに顔を出す
  • インターネットで情報収集し、常に最先端を追う努力をする

Tip 9 見聞きしたものごとを批判的な目で分析すること

例えばブログにそう書いてあったから正しいとか、上司からそのように習ったから正しいとか、みんなそうしているから正しいとか、そんなのは正しいとは言えない。物事を批判的な目で捉え直し、技術的探究心を深めること。

Tip 10 伝える事柄と、伝える方法は車の両輪だと考えること

  • 自分の言いたいことを明確に
  • 聞き手のことを思いやる
  • 話すタイミング・スタイルを考える
  • 自分も良い聞き手になること

これはとても興味深かった。これらを端的に言い換えるならば「プログラマにはコミュ力も必要」ということ。きちんと物事を適切な方法で伝えること。

Tip 11 DRY

Don’t Repeat Yourself. これは説明するまでもないだろう。重複を避ける。同じコードのコピーを3回以上行ったら共通化、同じ作業を三回以上行ったら自動化。

Tip 13 関係ないもの同士の影響を小さく

疎結合なコンポーネントを設計すること。このようなコード設計を行うことで下記のメリットが得られる。

  • 生産性が向上
  • 再利用性が向上
  • (各コンポーネントが独立しているので)問題を局所化できる
  • 堅牢なコードとなる
  • テストがしやすい

じゃあどうコードを切り分けていけばいいかというと、DDDでいうところのレイヤードアーキテクチャ的な設計が推薦されている。またはRails的なMVCアーキテクチャも紹介されている。

コードの設計をきっちり考えるのとともに、下記もしっかりやっていくように推奨されている。

  • コードのリファクタリング
  • コードのテスト
  • ドキュメンテーション

関連Tips

Tip 36 モジュール間の結合度を最小にすること

Tip 42 モデルからビューを分離する

Tip 15 目標を見つけるには曳光弾を使うこと

プロトタイプ vs 曳光弾という対比で出てくる話(個人的にはこの曳光弾という例えはあまり日常的に出てくる言葉ではないのでわかりにくい)。説明すると、プロトタイプ実装は実装が捨てる前提で作られるものである(コンセプト実装)一方、曳光弾開発はそのコードを捨て去るのではなくその後も使われる前提での初期実装を行うことである。メリットは下記の通り。

  • 早いうちからユーザーにものを提示できる
  • 開発者のモチベーションアップ
  • テスト用のプラットフォームが用意される
  • デモが可能になる
  • 進捗が明確に

今風の言葉で言うとアジャイル。まとまったものを丁寧に作るのではなく、さっさと動くものを作ってそれをBeta公開してフィードバックをもらったほうがうまく回るよねという話。今ではわりと常識ですかね。

Tip 22 1つのエディタを熟知

現代の開発では1つのエディタに固執するよりは、開発内容によって適切なエディタ/IDEを選ぶ時代だと個人的に思っているので、開発物に応じた複数のエディタ/IDEを使いこなせるほうが良いと思う。

と思う一方で、それでもなお1つのエディタに習熟することは大事だと思っている。なぜなら1つのエディアを熟知することでアナロジー的に他のエディタの慣れも早くなるし(「Aエディタでできるあの操作をBエディタではどうやるのだろう」という具合)、熟知しているエディタのパワフルな機能を駆使することで、汎用的なテキストエディット作業時にグンと生産性が向上する場合もあるからだ。

Tip 23 常にソースコード管理を使用

言うまでもなく、Gitを使うのは当たり前の時代になったし、GitHub(GitLab)でソースコードレビューするのも当たり前となった。

Tip 27 仮定せずに、証明すること

「このバグはこれがきっと原因だろうから、こうすれば直るだろう」「なんかわかんないけど動いた」「この対応で問題は解決しました(未検証)」はやめる。

バグが発生したならなぜそのようなバグが発生したのかを考えること。そしてそれはテストコードで再発は防止できるのか。同種の問題が他にもないのか。将来同じバグを踏まないためにはどうしたらよいか。そのバグの内容はきちんとチームで共有されているのか。

エンジニアであれば、「きっと〜だろう」という仮定ではなく、ロジカルに/テクニカルに物事に白黒付けよう。

関連Tips

Tip 44 偶発的なプログラミングはしない

実行するタイミングによって動いたり動かなかったりするようなプログラムは書かない。

Tip 29 コードを生成するコードを作成すること

銀の弾丸はない。がrails new, rails generateのような便利なコードジェネレータが予めフレームワーク側で用意されてある場合も多いので、積極的に使っていこう。

Tip 30 あなたは完璧なソフトウェアを作れない

あなたがどんなに優れた開発者であろうと完璧なソフトウェアを作るのは不可能だ。ソフトウェアには多かれ少なかれ必ず何かしらの問題はあるものだ。

対抗する手段として本書で紹介されているのが、防衛的コーディング表明プログラミング契約による設計 だが内容は割愛。興味があれば調べてみてほしい。

関連Tips

Tip 32 早めにクラッシュさせる

Tip 34 例外は例外的な問題のみに使用すること

Tip41 並列性を意識した設計を行うこと

GoのGoroutineのような軽量スレッド的な仕組みで並列処理もかつてよりはとてもやりやすくなったように思う。きちんと並列性を考慮してアプリケーションを設計し、高いパフォーマンス要求にも応えられる作りにしておくこと。

Tip 45 アルゴリズムのオーダーを見積もること

あるコストのかかる処理があったとして、そのオーダーを見積もってみること。それによってその処理がソフトウェアのパフォーマンスに与える影響度も想像できるはずだ。

Tip 46 見積もりの検証を行う

単純に見積もりだけでは終わらせない。仮定するのではなく、きちんと計測すること。

早まった最適化にも注意が必要。アルゴリズムの改良はそれが本当にボトルネックになっていることを確認していから行うもの。さもなければただの時間の無駄遣いに終わる。

Tip 47 早めにリファクタリング、こまめにリファクタリング

Tip4の割窓にもつながってくる話。リファクタリングを継続的に行いコードの健全性を保つ。そうすることで達人プログラマの精神衛生も保たれる。

リファクタリングの対象となるコード例としては下記の通り。

  • DRY原則に反しているコード
  • 時代遅れのコード
  • パフォーマンス悪化しているコード

リファクタリングを止めない

上司は納期が厳しくリファクタリングに使っている時間はないというかもしれない。しかしそれはリファクタリングを止める理由にはならない。将来問題が発生したときに生じるであろう大量の時間投資のことを考慮にいれること。開発者はときに上司を説得する必要があるかもしれない。

リファクタリングのコツ

  1. リファクタリングと機能の追加を同時にやらない
  2. リファクタリングを始める前にテストをしっかり用意
  3. リファクタリングの各作業は小さな単位にまとめ、慎重にすすめること

Tip 48 テスト設計を行う

これもかつてよりも当たり前になってきてますがテストをきちんと書くこと。テストフレームワーク、CIサービスなどでかつてよりテストは書きやすくなっている時代だ。

関連Tips

Tip 49 ソフトウェアをテストすること、さもなければユーザーにテストを強いることになる

Tip 62 早めにテスト、何度もテスト、自動でテスト

テストは自動化して何度もテストできるようにしておくこと。

Tip 63 テストがすべて終わるまでコーディングは終わらない

テストが完了してコーディングは終わったといえる。何をテストするかというと下記の通り。

  • 単体テスト
  • 結合テスト
  • 妥当性確認・検証
  • リソース消費、エラー、リカバリ
  • パフォーマンステスト
  • ユーザビリティテスト

Tip 54 プロジェクト用語集を作ること

DDD的にいうとユビキタス言語。プロジェクトによってはもしかしたら「クライアント」と「顧客」を使い分けているかもしれない。きちんとチーム内で用語に対する定義の共通認識を持っておくこと。

Tip 55 枠にとらわれずに考えるのではなく、枠を見つけること

手に負えない問題に直面したらすべての手段を列挙して考えてみる。下記を自問してみよう。

  • もっと簡単な手段はないか?
  • 本当の問題を解決しようとしているか? それとも末端の技術的問題に引っかかっているのか?
  • それがなぜ問題なのか?
  • 解決を難しくしている原因は何なのか?
  • この手段でやり遂げなければならないのか?
  • そもそもそれは解決しなければならない問題なのか?

この問いの中でなにかひらめきが出てくるかもしれない。

Tip 61 手作業は危険

最大の敵はプログラムのバグではなく、人間かもしれない。手動オペレーションによりヒューマンエラーを経験した開発者は少なからずいるのではないだろうか。人間は繰り返し作業は得意ではないので、そういう作業は自動化してプログラムにやらせよう。

Tip 67 日本語をもう一つのプログラミング言語として扱う

つまりソースコード上に書かれた日本語も含めてソースコードということである。

ソースコード自体がHowを表しているのでコメントにはWhy(目的・ゴール)を記述すること

Tip 69 ユーザーの期待を少しだけ上回ること

ユーザーの期待以上の良いものを作れるように心がけよう。

さいごに

古典だけど良書なので一読する価値はアリ。古きを知りて、今を自戒しよう。

  1. 当時の技術水準に照らし合わせて本書のアプローチがどれだけ先進的だったか想像してみるのも面白いかもしれない 

  • このエントリーをはてなブックマークに追加