【技術書記録003】「プリンシプル オブ プログラミング3年目までに身につけたい一生役立つ101の原理原則」要点メモ

今回の技術書

プリンシプル オブ プログラミング3年目までに身につけたい一生役立つ101の原理原則 | 上田 勲 |本 | 通販 | Amazon

会社の方にオススメされたので読んでいきます。



第1章 前提 〜プログラミングの変わらぬ真実〜

・プログラミングの成果物であるソフトウェアは、本質的に「困難性」をもつ。「複雑性」「同調性」「可変性」「不可視性」の4つで表される。
・その最たる要因は「複雑さ」。ソフトウェア開発の歴史は、複雑さとの戦いの歴史。
・プログラミングは「設計」であり、成果物であるコードは「設計書」。
コードは必ず変更・修正されるもの。読みやすく、変更に強いコードを書く。



第2章 原則 〜プログラミングのガイドライン

・コードを書くとき、最優先の価値を「単純性」「簡潔性」に置く。
・コードがシンプルであり続けることに「愚直」に取り組む(KISS)。
・必要になったとき、必要な分だけ書く(YAGNI)。「今自分が書いているコードは本当に必要なものなのか?」。汎用性よりも単純性という価値基準。
コードの重複は厳禁(DRY)。重複を避けておくと、長い目で見ると有利になる、というのが歴史の結論。
・「書きやすさ」よりも「読みやすさ」を重視する。書くより読む時間のほうがはるかに多い。
コメントには「Why」(なぜそれをしているか)を表現する。
・高いレベルの抽象化概念(高水準)と低いレベルの抽象化概念(低水準)を分離する(SLAP)。
→関数を構造化する。それにより各関数は、自身より1段低いレベルの関数を呼び出す処理が中心となる。
・「拡張に対して開いている」と「修正に対して閉じている(修正がその他のコードに影響しない)」の2つ同時に満たすよう設計する(OCP)。
命名は最重要課題。コードは読む人へのUI。名前にはより多くの情報を詰め込む。名前は「効果」と「目的」を説明する。



第3章 思想 〜プログラミングのイデオロギー

・技術は、問題解決のために試行錯誤を繰り返し、今の形になっている。技術を学ぶときは、動作原理や進化の過程、設計の背景にあるものを同時に知るようにすると、目的が達成されやすくなる。
・プログラミングセオリーを支える3つの価値:コミュニケーション>シンプル>柔軟性 の優先順位
→読む側のことを考える、複雑性を取り除く、拡張性を上げる

プログラミングセオリーを実現する6つの原則
 ①結果の局所化:変更の影響の局所化(ex:モジュール)
 ②繰り返しの最小化
 ③ロジックとデータの一体化:近くに配置
 ④対称性:「追加」メソッドの対になる「削除」メソッド、あるグループにある関数は同じ引数を取る、あるモジュール内のデータはすべて生存期間が同じ、ある関数内で呼び出す関数の抽象度は同じレベル、等
 ⑤宣言型の表現:解くべき問題の性質や満たすべき制約を記述)
 ⑥変更頻度:変更タイミングが同じコード(関連性の高いコード)をまとめる、単一責任の原則

アーキテクチャ根底技法
 ①抽象:線引き、捨象(特定の性質に注目)と一般化(共通の性質を抽出)
 ②カプセル化モジュール化、関連の深いデータと関数をまとめる
 ③情報隠蔽内部を隠蔽、外部からのアクセスは限定
 ④パッケージ化:モジュールのグルーピング、ボトムアップで決定していく
 ⑤充足性、完全性、プリミティブ性:十分か、欠けていないか、純粋か
 ⑥関心の分離:他のモジュールとの結合を最小限に、関心単位で分離
 ⑦ポリシーと実装の分離:ポリシー:ソフトウェア特有、実装:他のソフトウェアでも使える
 ⑧インターフェースと実装の分離:使用者が知るのはインターフェースだけ、実装の詳細は知らない
 ⑨参照の一点性:変数の単一代入
 ⑩分割統治:大きな問題を小さな問題に分割して各個解決

アーキテクチャ非機能要件
機能面以外の全般についての要件(変更容易性、相互運用性、効率性、信頼性、テスト容易性、再利用性)。アーキテクチャの設計時点から考慮されるべき観点。
 ①変更容易性:保守性、拡張性、再構築、移植性。ソフトウェアエージングを防ぐためには、「正確なドキュメント化」「変更時にアーキテクチャを壊さない」「真摯なレビュー」「変更箇所を予測した柔軟な設計」等が重要。
 ②相互運用性:他のソフトウェアと連携できる能力。プロトコルデータ形式の選定において、業界の標準的な規格を選択する。
 ③効率性:時間効率、資源効率。
 ④信頼性:例外的な場面、予期しない方法や不正な方法で使用されても、機能を維持する能力。
 ⑤テスト容易性:効果的かつ効率的にテストを行う能力。モジュール間の依存関係の排除がポイントに。極力、依存関係を排除し、小さい単位でテストが可能になるよう設計する。
 ⑥再利用性:再利用「する」「される」能力。

7つの設計原理:どうしたら開発時に障害を作り込まないようにできたか、コード妥当性のレビュー観点。
 ①単純原理:シンプルにこだわる。複雑で全体的な関連性を重視するのではなく、局所的な完全性を重視する。
 ②同型原理:同じことは同じように扱う。→違うものが目立つようになる。
 ③対称原理:形の対称性にこだわる。→読むときに予測がつく。
 ④階層原理:構造が階層であることにこだわる。→階層構造は読みやすい。
 ⑤線形原理:処理の流れを直線的に読めるようなコードにする。
 ⑥明証原理:一見して明らかに正しいと言えるコードを書く。ロジックは直感的でわかりやすいものにする。
 ⑦安全原理:ありえない条件をあえて考慮してコードを書く。

UNIX思想・哲学: この節は出典書籍にある「UNIXという考え方ーその設計思想と哲学」をすでに読んでいるので省略。そっちを読んだ方がより深く知れるので。



第4章 視点 〜プログラマの観る角度〜

・凝集度(モジュール強度):独立性を高めるには、各モジュール内での関連性が最大になるように、モジュール間の関連性が最小になるようにする。
・結合度:結合度を低くするには、
 ・データの受け渡しはできるだけ引数で行う。
 ・データの置き場所はできるだけグローバルにしない。一瞬しか必要しないものはローカル変数に。
 ・渡す値に応じて変わるようなコードを書かない。

・可逆性:最終決定というものは存在しないので、元に戻せないような決定をしない。
・コードの臭い:その兆候を把握する。重複、長大、不適切な名前。
・技術的負債:素早く返すことが何よりの対策。積極的にリファクタリング



第5章 習慣 〜プログラマのルーティン〜

プログラマの3大美徳:怠慢、短期、傲慢。ハードワークはしない。
ボーイスカウトの規則:前より少しでもきれいにする。コードをリポジトリから取得したときよりもきれいにしてコミットする。
・パフォーマンスチューニングは「よい(正しく読みやすい)コード」を作成した後に行う。
・プログラミングにおいてはエゴを捨て去る。体内的にも対外的にも。
・プログラミングは、一度に小さな1つの作業を行う。後戻りが楽になる。



第6章 手法 〜プラグラマの道具箱〜

・曳光弾(先行的にプログラミングした、実際に動作する本物コード)のアプローチを採る。プロトタイプは使い捨てであり、曳光弾の前に行うもの。
・契約による設計:関数を呼び出す側は「想定(事前条件)」を、呼び出される関数は「確約(事後条件)」を守る。ユーザーの入力チェックは関数を呼び出す前に、関数を呼び出す側で行う。関数側のアサーションを入力チェックに使用しない。
・防御的プログラミング:「かもしれない」プログラミング。想定内・想定外エラーの両方に対処。
・言語の「中で」ではなく、「中へ」プログラミングする。表現するものを決めてから、どうやって実現するか考える。
・ラバーダッキング:問題のあるコードを「誰か」に説明することで、問題の原因に気づく。
コンテキスト:周りの状況や背景、文脈。コードを書くときは、コンテキストを先に示す。着眼大局、着手小局。
・ソフトウェアで問題を真に解決するには、解放(アルゴリズム)に関する知識だけでなく、問題に対する正確な知識も必要。問題を取り巻く領域(ドメイン)をコンテキストとして考察する。



第7章 法則 〜プログラミングのアンチパターン

ブルックスの法則:スケジュールの遅れに対して、人員追加はさらなる遅延を招く。リスケジュールしかない。
コンウェイの法則:アーキテクチャは、それを作った組織を反映する。先によいアーキテクチャを設計して、そのアーキテクチャに組織を合わせるようにすべき。
・割れた窓の法則:悪い設計、間違った意思決定、悪いコードを放置すると、ソフトウェア全体をごく短期間で腐敗させる。
エントロピーの法則:コードは自然と腐っていく。無秩序へと向かう。
・80−10−10の法則:ユーザー要求の80%は短時間で実現できるが、10%は相当な努力が必要となり、最後10%は実現不可能。
・ジョシュアツリーの法則:その名前を知った途端、そのものが見えるようになる現象。チームで統一した共通言語を使用する。
・セカンドシステム症候群:2番目のリリースバージョンは、多機能にしすぎてしまい、品質が悪く使い勝手がも悪くなる傾向。ユーザーを考えて陥らないようにする。
車輪の再発明:既存の技術があるのに、もう一度自分で発明してしまうこと。エゴは排除する。
・ヤクの毛刈り:問題を解こうと思ったら、さらに別の問題が出てきて大元の問題の解決に辿りつかない現象。メモを取りながら作業することが重要。



あとがき

プログラマのコードの先には、それを読む仲間がいる。そして、成果物であるソフトウェアを使う人がいる。これらの人々を意識しながら、コンテキスを読み、バランスを持った選択を行うようにする。



長い本だった。いきなり101の原則すべてを実行することは困難だが、経験を積みながら一つ一つを意識していきたい。すべてに根底することは、あとがきの一節にまとまっているのではないだろうか。読む人・使う人のこと常に意識しながらコードを書いていきたい。