書籍 プリンシプルオブプログラミング 第3章 下 まとめ
3.37 UNIX思想
UNIX思想
3.38 モジュール化の原則
控えめなモジュールを作る
モジュールの作成は、以下のように行なう - 連性の高いコードのみで構成する - 問題や変更を局所化できる - インタフェースにおいては、とにかく余計なモノを無くして、シンプルにする(入り口を狭く)
3.39 明確性の原則
コードを明確にする
- とにかく読みやすいコードを書く
- 多少のパフォーマンスよりも可読性
3.40 組み立て部品の原則
フィルタにして組み立てる
フィルタ:入力値を加工して、別の値として出力するソフトウェア
より多くのソフトウェアとやり取りするためにも、以下のようなことを意識してソフトウェアを設計する
- 無駄に凝った設計をしない
- テキスト形式でデータを送受を行なう
- シンプルにデータを送受できる
- 異なる実現方法を取っているソフトウェアとも連携しやすくなる
3.41 分離の原則
メカニズムからポリシーを離す
ポリシー
- ビジネスロジックやUIなどの、ソフトウェアが依存する
- ソフトウェアが作られる目的、前提に近い
- 比較的不安定(変更される可能性が高い)
メカニズム
- アルゴリズムやエンジンなどの、ソフトウェアに依存しない部分
- ソフトウェアの内部的な処理、実現手段
- 比較的安定
相互を繋いでしまうと、以下のようなデメリットが発生してしまう。
反して、それぞれを独立して取り扱うことで以下のような恩恵を得られる。
3.42 単純性の原則
コードはシンプルにする
自分のエゴや機能を増やしたいという理由から、コードは自然に複雑化していってしまうため、とにかくシンプルに保つことを意識する。(美徳化)
3.43 倹約の原則
分量や複雑さをなるべく小さく留めることで、保守する際の負債を減らすことが出来る。 また、コードを小分けにして、大きめのコードに継ぎ足しはしないようにする
3.44 透明性の原則
ソフトウェア動作の見える化
ソフトウェアのデバッグをやりやすくするために、設計時から以下のことを意識して設計する。
透明性
- 一目見て、ソフトウェアがどんな動作をしているのか理解できるようにする
開示性
- ソフトウェアの内部を監視すること
- ログを取るなど
デバッグを簡単にする仕組みを、積極的に本番コードにも組み込んでいく。
3.45 安定性の原則
ソフトウェアを安定させる
コードが複雑になっていくと、
「理解が追いつかない」
↓ ↑
「把握できていないところで障害 (理解できていないため、発生確率高)」
というスパイラルに陥るため、理解しやすいよう「透明性」と「単純性」を満たすコードを記述する。
3.46 表現性の原則
コードにおける情報の表現は、ロジックではなくデータに寄せて記述するようにする。 また、処理の複雑化を避けられない場合、コードよりもデータ構造を複雑にした方が分かりやすくなる。
3.47 驚き最小の原則
インタフェースは、利用者が想像するであろう形に設計し、利用者が見た際に、悪い意味で驚かせないようにする。 また、利用者の想像に近づけることで、元々持っている知識を使うことができて、学習コストを抑えられる。
方法
よく似たソフトウェアのインタフェースをモデルにする
- 同じような機能を持ったソフトを参考にしてUIや操作系を設計する
想定ユーザーの特徴を考慮する
- ユーザーが誰なのかを考えて、想像のレベルがどこにあるのかを考慮する
伝統に注意を払う
- その機能を持ったソフトウェアにおいて、伝統的に使用されているファイルの形式やショートカットなどを参考にする
- 伝統的に築かれた手段は、学習コストを低減する
「一見似ているが異なる」を避ける
- 「一見同じだが微妙に違う」機能を実装する際は、見た目も大きく異ならせた方が、間違いにくく親切
3.48 沈黙の原則
ソフトウェアは余計な出力を行わずに、重要な情報のみを表示する。
- 余計な出力があると、重要な出力が埋もれてしまう
3.49 修復の原則
ソフトウェアでエラーの回復に失敗した場合、思わぬ障害を発生させてしまう可能性もあるため、処理を中断すること。
また、エラーはなるべく早い段階で派手に通知して、ユーザーに気づいてもらえるようにする。
3.50 経済性の原則
時間を大切に
時間は限られているので、以下のような理由でなるべく浪費しないこと
マシンスペックの不足
- ハードの基本性能が不足していると、あらゆる処理に時間がかかってしまう。
使用するツールの制限
- 必要なツールを利用できないと、「別のソフトを探す、インストール、操作方法を勉強」「別の方法を考える」のように時間の浪費に繋がってしまう
環境に関するルールや制限
- ネット環境の使用禁止などによって、必要なサイトや情報へのアクセスが失われてしまう
3.51 生成の原則
コードを書くためのコードを書く
人間がコードを記述するよりも、コードにコードを自動生成させた方が「安価(人が書かないため)」で「高品質(機械が書くためミスが少ない)」というメリットを得られる。
3.52 最適化の原則
早いコードより正しいコード
コードの処理を早めるために最適化するより、冗長でも必ず動くコードを書くこと
早い段階から「速いコード」を設計しない
透明性や単純性が犠牲になる
- コードの可視性が低下したり、より複雑なものになってしまう
部分の最適化が、全体の妨げに
- 全体に足並みを揃えずに部分の最適化を行なうと、全体の最適化で得られる効果が薄くなってしまう
プロトタイプの作成などによって、徐々に早いコードにしていくことが効果的である。
3.53 多様性の原則
多様性の許容
「正解は一つ」という考えは持たずに、他の手段を否定しないようにして、よりよい手段を求め続けること。
3.54 拡張性の原則
ソフトウェアは追加の機能実装などで変更されるモノであるため、未来に備えた設計をしておく。
3.55 UNIX哲学
UNIXにおける哲学
3.56 小は美なり
小さなソフトウェアは、理解しやすかったり、マシンリソースへの負担の低減も期待できる。
3.57 1つ1仕事
1つのソフトウェアに1つのみの仕事を実装することで、以下のようなメリットが期待できる。
ソフトウェアの本質を見失わなくなる 問題解決を行いやすくできる 理解しやすくなる
3.58 即行プロトタイプ
出来るだけ早くプロトタイプ着手
実際にデブロイする完成品では無いため、アイデアを試行錯誤するためにも、早い段階でプロトタイプを実装する
3.59 効率性より移植性
「開発効率性」と「移植性」なら、移植性を優先すべき。
環境に依存しないソフトウェアにすることで、移植の際のコード修正を少なく済ませることができ、ソフトウェアの価値を維持できる。
3.60 データはテキスト
データをテキストファイルにまとめることは、以下のようなメリットがある。
移植性
- テキストファイルは多くの端末に対応している
可視性
- 人間にとって確認しやすく、エディタなどで簡単に編集できる
ツール、コマンド
- ツールやコマンドにとって扱いやすく、バイナリ形式の変換などを気にする必要が無くなる
また、テキストファイルの形式には、標準規格のもの(CSV,XML,JSONなど)を使用することで接続性の向上も見込める。
3.61 レバレッジ・ソフトウェア
ソフトウェア同士を連携させて、ソフトウェアの価値をコスパ良く高める。
少ない労力で巨大な成果を得る
他人のコードを借りることで、少ない労力でソフトウェアの機能を実装できる。(勿論十分に理解した上で)
手作業を自動化する
人間が手作業していたものを自動化することで、「手間」「ミス」「時間」「コスト」の全てを減らせるため、正確性と生産性の劇的な向上が見込める。
3.62 シェルスクリプト
シェルスクリプトによって、梯子の効果と移植性を高める。
梯子の効果
- シェルスクリプトを利用することで、他のソフトウェアやコマンドを繋げる
- 多くのプラットフォームで使用できれば、伴ってより多くの人に利用される可能性が上がる
移植性
3.63 対話インタフェース回避
ユーザーとソフトウェアが対話する形式を利用すると、以下のような弊害が出てくる。
- ソフトウェアごとに専用の対話方法を覚えなければならない
- ソフトウェアとの対話ができなくなる
- 人間の入力時間がボトルネックになる
- 入力部分がコードを大型化させてしまう
3.64 フィルタ化
ソフトウェアをフィルタとして設計する(データを入れたら処理されて出てくる)
ソフトウェアとは入出力である
データは人間が生成するもので、ソフトウェアは何かを生成するのではなく、あくまでデータの処理に徹するのが本来の姿である。
UNIX哲学・小定理
ざっくり解釈
環境カスタマイズ
UNIXの設定を細かく、ユーザ好みに行えること。 最初は戸惑うし、細かい設定を突き詰めるのに苦労するが、一度完璧な設定が出来上がってしまえば、非常に操作性のよい環境が出来上がる。
小文字使用
基本は小文字を利用すること。 目への負担の低減や、その中で大文字を使えばより目立たせることが出来る。
沈黙は金
重要な情報のみを表示し、小さなエラーは表示しない。(重要な情報が埋もれてしまうから)
90パーセント解
90から100の壁は非常に分厚いため、90%の完成度に抑えておく方がコスパがいい。
劣るが優る
「高品質高価」より「コストはそこそこだが、効率的」なシステムの方が、受け入れられやすいという考え方