#author("2017-05-28T06:10:40+00:00","default:admin","admin") #author("2017-05-28T06:29:49+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] -凝集度 ... モジュールは「純粋」に <= 雑じり気のあるモジュールは脆い => 高強度モジュールを目指す --Lv.1:暗号的強度 ... モジュール内の要素間に特別の関係が認められない --Lv.2:論理的強度 ... ある機能を抽象的に捉えてまとめたもの --Lv.3:時間的強度 ... 特定の時点(時間)に連続して実行する機能を1つのモジュールにまとめたもの --Lv.4:手順的強度 ... 問題を処理するために関係している複数個の機能のうちのいくつかを実行する --Lv.5:連絡的強度 ... 手順的強度の特性を持ちつつ、モジュール内機能間でデータの受け渡し(連絡)をしたり、同じデータを参照する --Lv.6:情報的強度 ... 特定のデータ構造を扱う複数の機能を、1つのモジュールにまとめたもの --Lv.7:機能的強度 ... モジュール内の全ての命令が1つの役割(機能)を実行するために関連しあっている -結合度 ... モジュール間は「疎遠」に <= 相互依存モジュールは脆い => 低結合モジュールを目指す --Lv.1:内容結合 ... あるモジュールと他のモジュールが一部を共有 --Lv.2:共通結合 ... 共通域に定義したデータを、いくつかのモジュールが共同使用するような結合形式 --Lv.3:外部結合 ... 外部宣言したデータを共有したモジュール間の結合形式 --Lv.4:制御結合 ... 呼び出し側のモジュールが、呼び出されるモジュールの制御を指示するデータをパラメタとして渡す結合形式 --Lv.5:スタンプ結合 ... 共通域にないデータ構造を、2つのモジュールで受け渡しするような結合形態 --Lv.6:データ結合 ... モジュール間のインタフェースとして、スカラ型のデータ要素だけを、パラメタとして受け渡す結合形式 --べき等性 ... ある操作を何回行っても結果が同じこと --安全性 ... 操作対象の状態を変化させないこと -直交性 ... コードは独立させよ <= 直交コードは堅牢 => コードのレイヤー化 -可逆性 ... 「UNDO」可能な選択をせよ <= 最終決定などない => 特定技術に依存しない -コードの臭い ... コードの凶兆を見逃すな <= 臭覚はリファクタリングの必要条件 => 臭いの傾向を知る -技術的負債 ... 問題コードは「借金」である <= 問題コードとうまく付き合う方法 => 問題コードを管理する *習慣 [#q993126e] -プログラマの3大美徳 ... プログラマは「怠慢」「短気」「傲慢」であれ => 「怠慢」「短気」「傲慢」で作業を仕組み化 => 「自動化」「ひな形化」「モジュール化」 --怠慢 ... 全体の労力を減らすために手間を惜しまない気質 --短気 ... コンピュータが効率的に処理していない、意図通りに動いていない場合に、直ちにコードを書き直す気質 --傲慢 ... 高いプライドを持ち、人様に対して恥ずかしくないコードを書く気質 -ボーイスカウトの法則 ... コードを掃除して帰る <= コードの腐敗を抑止する => コードは改良してからコミット -パフォーマンスチューニング’ ... 「速い」コードより「よい」コード <= 速いコードは「割に合わない」=> まず「よいコード」を書く -エゴレスプログラミング ... エゴを捨てよ <= エゴレスで品質向上 => エゴレスプログラミングの十戒を守る --自分自身も間違いを犯すということを理解し、受け入れます --書いたコードは自分自身ではありません --どれほど極めたと思っていても、上には上がいます --相談なしにコードを書き直しません --自分よりもスキルが劣る人にも、尊敬と敬意と忍耐を持って接します --世界で唯一変わらないことは、変わるということだけです --本当の権威は、地位ではなく、知識から生じます --信じるもののために戦います。ただし、負けは潔く受け入れます --部屋に篭りきりはいけません --「人に優しく、コードに厳しく」して、人ではなくコードを批評します -1歩ずつ少しずつ ... ステップ・バイ・ステップ <= 「手堅い歩み」は効率的 => 一度の複数やらない -TMTOWTDI(There's more than one way to do it.)... ツールの多様性は善 <= 対象が多様なら手段も多様 => 選択肢をたくさん用意 *手法 [#t738aff1] -曳光弾 ... -契約による設計 ... -防御的プログラミング’ ... -ドッグフィーディング ... -ラバーダッギング ... -コンテキスト ... -曳光弾 ... 最終形にも残る「骨格コード」<= 暗闇の中で道筋を照らす => 最初に動作する土台を作る -契約による設計 ... 「呼び出し側」と「呼び出される側」の取り決め <=「思い違い」の早期発見 => コメントとアサーションで契約 -防御的プログラミング’ ...「かもしれない」プログラミング <= 開発と運用の安全運転 => バリケード戦略 -ドッグフィーディング ... ソフトウェアの「味見」<= ユーザの視点を手にいれる => 自分でユーザのように使う -ラバーダッギング ...「説明する」というデバッグ <= 自己解決を促す => 無機物に説明 -コンテキスト ...「文脈会話」「文脈思考」<= 会話や思考を迷子にしない => コンテキストを示す *法則 [#s3a34021] -ブルックスの法則 ... -コンウェイの法則 ... -割れた窓の法則 ... -エントロピーの法則 ... -80-10-10の法則 ... -ジョシュアツリーの法則 ... -セカンドシステム症候群 ... -車輪の再発明 ... -ヤクの毛狩り ... -ブルックスの法則 ... 要員追加は「火に油」<=「人」と「月」は交換不可能 => リスケジュールせよ -コンウェイの法則 ... アーキテクチャは組織に従う <= アーキテクチャはコミュニケーションに従う => アーキテクチャ設計後に組織編成せよ -割れた窓の法則 ... 悪いコードは「蟻の一穴」<= 悪いコードは邪心を引き出す => コードは「清潔」に保つ -エントロピーの法則 ... コードは自然と腐っていく <= コードは無秩序へ向かう => コード腐敗の兆候をつかむ -80-10-10の法則 ... プログラミングに万能薬はない <= プログラミングの問題領域は広すぎる => ツールの使用は適材適所 -ジョシュアツリーの法則 ... 名前がないものは見えない <= 名前を知ることで存在を知る => ユビキタス言語を使用する -セカンドシステム症候群 ... 2番目のリリースは機能過多 <= 慣れると「多機能主義」=> ユーザを考える -車輪の再発明 ... 既にあるのに作る <=「車輪を知らない」「車輪を作りたい」=>「車輪」以外に注力する -ヤクの毛狩り ... 本当の問題にたどり着かない <= トラブルは芋づる式 => 早々に切り上げる