#author("2017-05-27T06:06:30+00:00","default:admin","admin") 書籍「プリンシプル オブ プログラミング」の書いてある内容を思い出すためのメモ書き *原則 [#e3bc7a7c] -KISS(Keep It Simple, Stupid または Keep It Short and Simple) -DRY(Don't Repeat Yourself) --One Fact in One Place --Once and Only Once -YAGNI(You Aren't Going to Need It) -PIE(Program Intently and Expressively) -SLAP(Single Level of Abstraction Principle) -OCP(Open-Closed Principle) -名前重要 *思想 [#i733017b] -プログラミングセオリー --3つの価値と6つの原則に支えられる **3つの価値 [#y5caf4ff] --コミュニケーション ... コードを読んだ人が、コードを理解し、コードを修正し、コードを使用することができる --シンプル ... コードの複雑性を排除する --柔軟性 ... コードの変更が容易である **6つの原則 [#b3d122e0] --結果の局所化 ... 変更の影響を抑える => 修正と確認が容易になる <= 関係が濃密なコードをまとめる --繰り返しの最小化 ... 重複を排除する => 修正の影響を局所化する <= コードを分割して管理 --ロジックとデータの一体化 ... データとその操作は近くに => データと操作は修正タイミングが同じ <= データと操作を同じ場所に --対称性 ... コードに一貫性を持たせる => 他の部分も類推できる <= 同じことは同じ表現で --宣言型の表現 ... 宣言型でプログラミング => フローがないと読みやすい <= 宣言型を取り入れる --変更頻度 ... 変更理由でグルーピング => 変更範囲が狭くなる <= 変更理由で所属を決める **アーキテクチャ根底技法 [#y06a6c84] -良いコードには以下の技法が使われている -抽象 ... 概念的な「線引き」=> 複雑さへの対抗手段 <= 「捨像」と「一般化」を駆使 -カプセル化 ... データとロジックをグルーピング => 抽象概念が混ざらない <= 仲間の要素をカプセルに込める -情報隠蔽 ... 必要にないものは見せない => 関連を整理してシンプルに <= 内側は隠蔽する -パッケージ化 ... モジュールをグルーピング’ => モジュール群の複雑度を下げる <= ボトムアップでパッケージを設計 -関心の分離 ... 関心ごとにコードを分離 => 関心単位で変更が行えるように <= 関心単位でモジュール化 -充足性、完全性、プリミティブ性 ... 表現が十分かつ完璧かつ純粋 => 表現している抽象を正確に伝える <= モジュールの抽象を隙なく表現 --充足性 ... モジュールが表現しようとしている抽象が、それを伝えるために十分であるか --完全性 ... モジュールが表現しようとしている抽象が、全ての特徴を備えているか --プリミティブ性 ... モジュールが表現しようとしている抽象が、全て純粋であるかどうか -ポリシーと実装の分離 ... 「ポリシー」と「実装」は混ぜない <= 「実装」は安定だが「ポリシー」は不安定 => 「ポリシー」と「実装」は別モジュール -インタフェースと実装の分離 ... 構成は「インタフェース」と「実装」から <= 使用者はインタフェースだけ知ればよい => インタフェースを用いて設計する -参照の一点性 ... 定義は一度きり => 副作用のないプログラミング <= 「単一代入」とする -分割統治 ... 大きな問題を小さく割る <= 大きなままでは制御不能 => 小さくして各個撃破 **アーキテクチャ非機能要件 [#k910c408] -「機能以外の機能」の観点 <= 非機能はリリース後に影響大 => 非機能観点で設計 -ソフトウェアが高品質であり、ユーザの役に立つためには、機能だけでなく「非機能」的な要件を満たさなければならない -非機能的な特性は、開発や保守、運用、コンピュータリソースの効率活用に大きな影響を及ぼす -リリース後の運用の「大きな」トラブルのほとんどが、パフォーマンスやシステムダウンなど、非機能的な特性に起因している -非機能要件の観点は以下の6つ -変更容易性 ... コードを容易に変更する能力 <= ソフトウェアの寿命は存外長い <= 保守性、拡張性、再構築、移植性 --保守性 ... 障害が発生したコードの修正のしやすさ <= 変更の局所化、他のモジュールへの副作用を最小にするアーキテクチャの採用 --拡張性 ... 新しい機能の追加、モジュールの新しいバージョンへの置き換え、不要な機能やモジュールの除去などのしやすさ <= モジュール間が疎結合 --再構築 ... モジュール間の関係の再組織化 <= モジュールの配置が柔軟にできること --移植性 ... 様々なハードウェア、OS、プログラミング言語などに適合させる際のやりやすさ -相互運用性 ... 他のソフトウェアと会話する能力 <= ソフトウェアは連携する => 標準規格を選択する -効率性 ... リソースをうまく使う能力 <= リソースは限られている => リソースを適切に利用 --時間効率性 ... スループット、レスポンスタイム、ターンアラウンドタイムなどで評価 --資源効率性 ... CPU使用時間、メモリ使用量、ストレージ消費量、ネットワーク伝送量などで評価 -信頼性 ... 機能を維持する能力 => 求められる機能維持レベルは様々 => 冗長化、フェールソフト、フェールセーフ、フールプルーフ --フォールトトレランス ... ソフトウェアに障害が発生したときに、正常な動作を保ち続ける能力 --ロバストネス ... 不正な使用方法や入力ミスからソフトウェアを保護する能力 -テスト容易性 ... 「効果的」かつ「効率的」ににテストする能力 <= テストの品質が本体の品質 => テストも考慮した本体設計 -再利用性 ... 再利用「する」「される」能力 => できるだけ「作らない」で開発効率化 <= 「プラグイン」アーキテクチャ --再利用の「3の法則」 ---難易度3倍の法則 ... 再利用可能なモジュールを作るのは、単一のソフトウェアで使うモジュールを開発する場合に比べて3倍難しい ---テスト3種類の法則 ... 再利用可能なモジュールは、共有化する前に、3つの異なるソフトウェアでテストする必要がある **7つの設計原理 [#f35cf12a] -コード妥当性レビュー観点 => コード価値観が「漏れない」「ブレない」<= コードを書くときにも使う -単純原理 ... シンプルにこだわる <= 複雑なところにバグが出る => 自然なコードを書く -同型原理 ... 同じことは同じように扱う <= 「異物’」は目立つ => 一貫性のあるコードを書く -対象原理 ... 形の対称性にこだわる <= 読むときに予測が付く => 対称性のあるコードを書く -階層原理 ... 階層にこだわる <= 階層構造は読みやすい => 抽象階層構造のあるコードを書く -線形原理 ... 処理の流れは直線にこだわる <= 一直線の処理は読みやすい => 分岐の少ないコードを書く -明証原理 ... ロジックの明証性にこだわる <= 不確実性を取り除く => ロジックが明瞭なコードを書く -安全原理 ... 安全性にこだわる <= 大事故への発展を防ぐ => 安全サイドにコードを書く **UNIX思想 [#t37c09ca] -UNIXの底流にある暗黙知 <= UNIXの設計判断の正しさ => UNIX思想に沿う -モジュール化の原則 ... 控えめなモジュールを作る <= モジュール関係が簡潔になる => モジュールの入口を狭くする’ -明確性の原則 ... コードを明確にする <= コードを読むのはマシンではなく人 => 明確でなければ改善する -組立部品の原則 ... フィルタにして組み立てる <= 相互接続で相乗効果 => テキストを入出力するコマンドを作る -分離の原則 ... メカニズムからポリシーを離す <= メカニズムは安定、ポリシーは不安定 => 分離したポリシーを改善 --メカニズム ... X Window System など、エンジン的な役割を果たす部分 --ポリシー ... ビジネスロジックやユーザインタフェース -単純性の原則 ... コードはシンプルにする <= コードは自然状態で複雑になる => シンプルを美しいとする文化 -倹約の原則 ... 大きなコードは書かない <= 大きなコードは制御不能 => コードを継ぎ足し続けない -透明性の原則 ... ソフトウェア動作の「見える化」<= デバッグに貢献 => 動作の「見える化」を機能化する --透明性 ... ソフトウェアの動作について、一目見てすぐに「何をどのようにしているのか」が理解できること --開示性 ... ソフトウェアの内部状態について、監視ないし表示できること -安定性の原則 ... ソフトウェアを安定させる <= ソフトウェアは堅牢でなければならない => コードを「透明化」「単純化」する --透明性 ... コードを見通すことができて、何が起きているのかがすぐにわかる --単純性 ... コードで行われていることが複雑でなく、全ての分岐条件を難なく説明できる -表現性の原則 ... 情報はデータに寄せて表現 <= データはロジックよりも御し易い => 複雑さをデータに寄せる -驚き最小の原則 ... 予想通りのインタフェース <= 学習コストを低く => ユーザの既知を活用する -沈黙の原則 ... ソフトウェアは寡黙であれ => 大事なことが伝わりやすい => 重要な情報のみ表示出力 -修復の原則 ... 修復失敗時は処理停止 <= エラー時の継続実行は被害拡大 => エラー通知は「けたたましく」 -経済性の原則 ... プログラマの時間を大切に <= プログラマの時間は貴重 => プログラマに投資する -生成の原則 ... 「コードを書く」コードを書く <= 生成コードは安価で高品質 => コードジェネレータを作る -最適化の原則 ... 速いコードより正しいコード <= 早い段階での「速いコード」は設計を破綻させる => 正しくしてから速くする -多様性の原則 ... 選択の多様性を受容する <= 人の想像力には限りがある => よりよいやり方を求め続ける -拡張性の原則 ... 拡張できる設計にしておく <= ソフトウェアは成長しなければならない => プラガブルな設計 **UNIX哲学 [#n4e60f85] -UNIXを支え続けている哲学 <= UNIXの哲学は普遍である => UNIX哲学を利用する -小は美なり ... 小さいソフトウェアは美しい <= 小さいソフトウェアは扱いやすい => 小さく作って小さく保つ -1つ1仕事 ... 1つのソフトウェアは1つの仕事 => ソフトウェアがピュアになる => 1つの仕事に集中 -即行プロトタイプ ... できるだけ早くプロトタイプ着手 <= 試行錯誤なしで良いものは作れない => プロトタイプで確度を高める -効率性より移植性 ... 効率性より移植性を優先 <= ソフトウェアの価値を持続 => ハードウェアに依存しないコードを書く -データはテキスト ... バイナリよりテキストファイル <= テキストファイルは万能型 => 標準規格のテキストファイル -レバレッジ・ソフトウェア ... ソフトウェアの梃子で力増幅 <= 少ない労力で巨大な成果を得る => 手作業を自動化する -シェルスクリプト活用 ... シェルスクリプトで接着する <= 梃子の効果を増幅する => グルー言語はシェルスクリプト -対話インタフェース ... 対話的ユーザインタフェースは避ける <= ユーザもマシンもソフトウェアも束縛される => コマンドインタプリタに制御を返す -フィルタ化 ... ソフトウェアはフィルタとして設計 <= ソフトウェアとは入出力である => 標準入出力を使う *視点 [#g4d0f8bd] -凝集度 ... -結合度 ... -直交性 ... -可逆性 ... -コードの臭い ... -技術的負債 ... *習慣 [#q993126e] -プログラマの3大美徳 ... -ボーイスカウトの法則 ... -パフォーマンスチューニング’ ... -エゴレスプログラミング ... -1歩ずつ少しずつ ... -TMTOWTDI ... *手法 [#t738aff1] -曳光弾 ... -契約による設計 ... -防御的プログラミング’ ... -ドッグフィーディング ... -ラバーダッギング ... -コンテキスト ... *法則 [#s3a34021] -ブルックスの法則 ... -コンウェイの法則 ... -割れた窓の法則 ... -エントロピーの法則 ... -80-10-10の法則 ... -ジョシュアツリーの法則 ... -セカンドシステム症候群 ... -車輪の再発明 ... -ヤクの毛狩り ...