書籍 プリンシプルオブプログラミング 第6章 まとめ

6章

手法 〜プログラマの道具箱〜

6.1 曳光弾

最終形にも残る「骨格コード」

対空砲の曳光弾のように、プログラミングでも挙動の軌跡を見えるように曳光弾を放つ。

プログラミングにおける曳光弾は、優先的に検証したい部分を先行的に実装すること。 本来の仕様より簡易なモノでも構わないので、実際の環境下で動作の確認をする。

曳光弾のメリット

実際の環境下で実装するため、精度の高いフィードバックを即座に得られる。

また、ソフトウェアを早いうちからユーザに見せられるため、早い段階からユーザのフィードバックを受けることができる。

プロトタイプとの違い

プロトタイプは、使い捨てのコードを繰り返し生成しながら学習し、曳光弾の前の下調べをすることが目的

6.2 契約による設計

「呼び出し側」と「呼び出される側」の取り決め

関数を呼び出す側は、関数に正しい引数を渡す責任がある。(事前条件)

また、関数側は正しい引数に基づいて、正しい処理を行なう責任がある。(事後条件)

この関係のように、双方で契約を結んでいると見なしてプログラミングすることを「契約による設計」という。

「思い違い」の早期発見

コードの正しさを保証できる

  • 要求されたことのみを実現するコード

コードをシンプルに出来る

  • 契約によって事前条件が満たされていると仮定できるため、余計な予測コードを書く必要がない

問題の早期発見が容易になる

  • 契約を果たせなくなった時点で、意図的にクラッシュさせることで問題の早期発見に繋がる
コメントとアサーションで契約

関数の契約内容をあらかじめコメントで伝えておくこと。

また、受け渡し前に「事前条件」「事後条件」の値が正確かチェックする。万が一不正確だったら、その時点でソフトウェアを停止させる。

トラッシュよりクラッシュ

コード実行中に想定できないことが起きたら、早めに停止させること。無理に続行させると、障害を抱えたコードが動き続けることになり、他の部分にも致命的な影響を与えかねない。

6.3 防御的プログラミング

かもしれないプログラミング

他の関数から不正な値を受け取るかもしれないという推測から、被害を受けないように防御的なコードを記述しておくこと。

外部ソースからの入力値チェック(想定内のエラー)

  • 入力値が適切な範囲内に収まっているか、文字列の長さが規定内かなどのチェック
  • 無効な入力を早い段階で検出して、エラー処理を適切に行なうようにする

関数の入力引数の値をチェック(想定外のエラー)

  • 別の関数から渡された入力引数のチェック
  • ここで不正な値を検出した場合、コードのにバグが存在していることになる
  • 不正な値を検出したら、即座に処理を停止
開発と運用の安全運転

「防御運転」によって、以下のようにプログラミングが安全になる。

開発中の安全運転

  • 不正を早めに検出できるため、場所の特定が容易になりデバッグ効率が上がる

運用中の安全運転

  • 不正を早めに対処することで、運用までに問題を持ち込まずに済むため、運用中の問題を防ぐことができる。
バリケート戦略

検証用のモジュールを用意し、必ずその部分を通さないと関数への値の引き渡しを行えないようにする。

「正当性」と「堅実性」

正当性

  • 不正確な値を返すくらいだったら何も返さない方がいいという考え方
  • 安全や命に関わるソフトウェアでは、事故を防ぐために重視される

堅実性

  • なるべく実行できるように手を尽くし、不正確な結果になっても実行が継続されるのであれば構わないという考え方
  • 一般向けのコンシューマソフトでは、こちらが重視される

6.4 ドッグフーディング

ソフトウェアの味見

開発者がユーザーになりきって、ソフトウェアを利用すること。以下のようなメリットがある。

  • 機能の使い勝手、過不足の発見
  • 使用する上での障害の発見

また、リリース後もサービス利用し続けて、サービスの便利さを証明する。

6.5 ラバーダッキング

説明するというデバッグ

プログラミングにおいて、問題を抱えている部分を誰かに説明すること。これにより、問題について思考を整理でき、自己解決できる可能性がある。

また、他人に説明するという名目上、暗黙の仮定を明確にする必要がある、 「説明ができなくなる部分」「ロジックとの整合が取れなくなった部分」に不具合箇所が潜んでいる可能性が高い。 まず、「順を追って内容を明確にする」ことが大事。

6.6 コンテキスト

コンテキスト:周りの状況や背景のこと

以下の側面から、コードを書く際にコンテキストを上手く組み込む。

コードの読み書きに利用

  • モジュールなどの各要素にコンテキストを明示することで、コードを読む際、それが何を意味しているかの説明

思考のツールとして利用

  • 物事の関係性を理解する手助けになる
会話や思考を迷子にしない

読み手にとって、コンテキストがあることで各要素同士の関係が明確になり、現在位置を見失わなくなる。

また、コードを読む際にまず「このコードは何を意味しているのか」を理解できるため、理解の効率が大幅に高まる。

達人になるためには

達人がどのように思考をしているか模倣する。コンテキストを認識して、問題のコンテキストを掘り下げ(絞り込み)、適切な対処を行えるように訓練をする。