Please enable JavaScript.
Coggle requires JavaScript to display documents.
プリンシプルオブプログラミング (2 原則プログラミングのガイドライン (KISS Keep it simple and short…
プリンシプルオブプログラミング
2 原則
プログラミングのガイドライン
KISS
Keep it simple and short
コードをシンプルに保つことで,読みやすく・理解しやすく・修正しやすくする
注意すべき考え
新しく覚えた技術を使いたい
将来の必要に備えたい
ほとんどの場合その機能は必要になることはない
ユーザーに判断を仰ぐより書いてしまったほうが楽
要件を決めるのはユーザーでありプログラマではない
不要なコードの保守にかかる時間と手間は雪だるま式に増えていく
less is more
単純化し,必要なものに絞ることで,様々な外的要因に耐えうることができる
DRY
Don't repeat yourself
同じコードを重複して書いてはいけない
同じロジックは共通の関数にまとめる
定数も変数定義してまとめる
コードに対する自明な説明は避ける
抽象化・共通化することで
コードの量が減り読みやすくなる
ロジックやデータに名前がつくのでコードが読みやすくなる
修正箇所が1つで済むので修正しやすくなり,品質を保てる
抽象化した部品は再利用しやすい
関連
継続的インテグレーション
繰り返し作業の自動化
デザインパターン
コードを再利用可能(拡張可能)にするためのコード構造パターンを提供
同じような問題について何度も考える「思考の重複」を防ぐ
重複する情報は一元管理できるようにする
DBとそれを用いるコード側には,テーブルのスキーマ情報が二重に必要になる
どちらかからもう一方が自動生成されるようにすれば,一元管理でき,修正漏れ等を防げる
データベースに格納させるデータの重複を禁止する (正規化)
更新異常を防ぐ
YAGNI
You Aren't Going to Need It
今必要なコードだけを書く
汎用性よりも単純性を重視する
余計な汎用性・拡張性は将来必要ない可能性があるだけでなく,コードを難しくし,修正しづらくしてしまう
「今日単純なことをして,明日変更が必要になったときに,変更のコストを支払う」 方が, 「今日複雑なことをして結局使われない」よりも良い結果を生むことが経験的にわかっている
つまりはアジャイル開発
PIE
Program Intently and Expressively
コードは人が読むためのものなので,
意図が伝わるように書く
コードを書く時間よりも読む時間のほうが圧倒的に長い
コードで表現されるのは What, How まで, Why はコメントに書く必要がある
コメントが必要無いくらいわかりやすいコードを書きつつ,それでも表現できない部分をコメントに書く
SLAP
Single Level of Abstraction Principle
高いレベルの抽象概念と低いレベルの抽象概念を分離する
機能の複雑さに応じて必要であれば多層に分離する
コードに「要約性」と「閲覧性」をもたらす
関数を構造化する
各関数は自信よりも1段抽象レベルが低い関数を呼び出す
名前で意図を伝えるためならば処理が一行でも関数にしても構わない
OCP
Open-Closed Principle
コードは
拡張に対して開いている
修正に対して閉じている
べき
コードの振る舞いを拡張できるが,拡張したとしてもその他のコードは全く影響を受けない
インターフェスを用いて複数のモジュールをつなげる
変更が発生しないのであれば,インターフェースは冗長で無駄なコードになるだけ
OCPの過度の適用を防ぐために変更の内容を予測しすぎないことが重要
ある程度割り切って,実際に変更が発生してから,同じような修正が必要ないように OCPを適用する
変更の内容自体ではなく,変化しそうな部分
を予測してOCPを適用する
変化がありそうな部分を見つけてインターフェースの裏に隠す 「流動要素のカプセル化」
GRASP : 責任駆動開発設計の手法
General Responsibility Assignment Software Pattern
変化が予想される不安定箇所との接点を識別し,接点の周辺に安定したインターフェースが気付かれるように責任を割り当てる
実現方法例
ポリモーフィズム
デザインパターン
Strategy
Observer
Template Method
Deorator
名前重要
名前を付ける行為は重要
適切な名前をつけるためには,その要素を正しく理解し,正しく設計する必要がある
名前そのものは重要
コードを通じたコミュニケーションを円滑化する
コードを読む時,関数名をみただけでその先の処理の概要が把握できるので適宜読み飛ばすことができる
コードを書く時,その関数を使用する場面で,名前に導かれて目的や使用方法がすぐに理解できるので呼び出すのが簡単
コードを読みたいから読むのではない,よく理解した上で,修正したり機能を追加するのが目的,目的に集中できるようにサポートすることが重要
Tips
名前を短いコメントだと考えて伝えるべき情報を詰める
複数候補を上げてそこから選ぶようにする
誤解されることの無いように気をつける, 各言語の慣例を知りそれにならう
効果と目的を説明する, 手段には言及しない
コードを読む人,使う人は詳細理解を省ける
処理を書く前にテストを書くことで,そのコードの使用者側の視点に立つ
検索可能な名前にする
名前可逆性:名前のもととなっった説明内容を復元できるかを確認する
3 思想
プログラミングのイデオロギー
プログラミングセオリー
3つの価値
シンプル
コードから余分な複雑性を排除し,シンプルにすることによってコミュニケーションしやすくする
他の人の視点に立つことでどの複雑性を捨てるかが明確になりやすい
過度なシンプル化には注意し,コミュニケーション第一のコードを心がける
柔軟性
コードは必ず変更されるので,変更しやすい柔軟なコードを作成することが重要
余計な柔軟性を言い訳に複雑性を正当化してはいけない
シンプルからスタートして,ユニットテストからボトムアップ的に得られる柔軟性の方が効果的
コミュニケーション
コードはコミュニケーションの場である
コードは自分が書くより他人が読む時間の方が長くなるので,他の人の視点に立ってコードを書く
.6つの原則
3つの価値をプログラミングの実践につなげる概念
結果の局所化
変更の影響が,局所的に留まるようにコードを構成する
モジュール化は再利用性とともに,そのモジュールへの変更の影響をモジュール内に留めることを目標にしている
段階的に必要な部分のみを読めばよく,コードを読む範囲,修正の影響範囲が絞られる
関係性の高いコードをまとめ,低いコードを分離しておくことが重要
関係性が高すぎるコードは逆に,一緒にするべき要素が分離されている可能性があるので注意 -> 機能の統合等も考える
繰り返しの最小化
重複したロジックを関数化して1つにまとめて共有コードにする
修正箇所が一つでよくなり,結果の局所化につながる
ロジックとデータの一体化
コードを修正する際に,ロジックとそのロジックが捜査するデータは大抵同じタイミングで変更する
同じコード上にあれば変更コストを抑えることができる
妥当なグルーピングは試行錯誤の中でわかることが多いので,一旦実装して,適宜修正していくのが良い
対称性
同じ種類のことは同じ様に表現する
追加メソッドがあれば,対となる削除メソッドも実装
ある関数内で呼び出す関数の抽象度は同じレベルにする
似ている部分が浮かび上がり,差異に気づきやすくなる
完全におなじになるのであれば重複を削除することができる
宣言型の表現
宣言型の表現
???
変更頻度
変更理由・タイミングでコードをグルーピングする
変更範囲,影響範囲が小さくなるので修正しやすくなる
単一責任の原則
モジュールを変更する理由は複数存在してはいけない
変更理由が複数あるということや,責任(役割)も複数あるということ
1つの役割の変更が他の役割に影響を及ぼしてしまう可能性が高い
技術を学ぶときは,動作原理や進化の過程,設計の背景にあるものも同時に知るようにする
「何のために」という目的を知らないと,知識が頭を通過するだけ
目的を理解していなければ,今回は適用できても次以降の場面で適用できない
アーキテクチャ根底技法
良いソフトウェアアーキテクチャ構築のための基礎原理
抽象
カプセル化
情報隠蔽
パッケージ化
関心の分離
充足性,完全性,プリミティブ性
ポリシーと実装の分離
インターフェースと実装の分離
参照の一点性
分割統治
抽象
概念的に明確な千匹を行い,それに従ってあるモジュールをそれ以外のモジュールから明確に区別する
捨象と一般化からなる
捨象:
複雑な対象のいくつかの性質を捨て去り,
特定の性質に目を向ける
今着目している側面から本質を捉える
一般化
:躯体的な対象から共通の性質を抽出し,より汎用的な概念にする
多くの対象に一律に適用可能な形にすることで
圧倒的に効率的に考えることができる
カプセル化
関連のあるデータとロジックをグルーピングして一つのモジュールを定義する
関連のない要素が混じらないのでコードが見やすい
変更時の影響がモジュール内で閉じる
影響範囲が明確になるのでコードを修正しやすい
独立した部品としての再利用性がt高まる
小さい単位に分割されるので複雑な問題を組み合わせで対処可能
情報隠蔽
モジュールの実装を,そのモジュールを
使用するクライアントから隠蔽する
どのようなデータがあり,関数がどのようなロジックで機能を実現するのか外部から隠蔽する
モジュールの持つデータには外部から直接アクセスできないようにする
クライアントが知る必要のない内部詳細を隠蔽すれば,インターフェースが小さくなり,やりとりがシンプルになり,コード全体の複雑性が下がる
コード変更の影響をモジュール内部に留めることができる
カプセル化と情報隠蔽は異なる概念であることに注意
一緒に語られ,一つの概念として紹介されることも多いが
パッケージ化
モジュールを意味のある単位でまとめてグループ化する
ソフトウェア全体がパッケージ単位に分割されるので複雑度が下がる
パッケージ内は関連のないモジュールが混じらないので管理しやすい
依存関係が整理され,パッケージ単位での再利用がしやすくなる
関心の分離
機能や目的でコードを集め,独立したモジュールとする
関心事に独立して修正できるので修正が用意 & 読む範囲を絞れる & 並行開発可能
MVC
アスペクト指向プログラミング
横断的関心事をうまく分離する技術
各機能横断のログ機能等
結合ルールを工夫雨して,各通常関(機能)にあとから組み込む
充足性,完全性,プリミティブ性
充足性
モジュールが表現しようとしている抽象が,それおを伝えるために十分であるか
Collection において add があるが remove が無いと Collection であることを伝えるには不十分 ?
充足でないと情報が不足して,利用できない
完全性
モジュールが表現しようとしている抽象が,全ての特徴を備えているか
Collection を表現するときに size が無いと完全とは言えない
完全でないとあとで足りない機能が出てきたときに困る
プリミティブ性
モジュールが表現しようとしている抽象が全て純粋であるかどうか??
Collection において add :があれば, add10 は必要ない
プリミティブでないと,インターフェースがシンプルでなく使いづらい
モジュールがどのような抽象を表現しているのか,3つの観点から明確にする
ポリシーと実装の分離
モジュールはポリシーもしくは実装
どちらかを扱う
ポリシーモジュール
ソフトウェアの前提に依存するビジネスロジックやその他のモジュールに対する引数の選択を行う部分 ??
ソフトウェアに特化しており,ソフトウェアの変更に伴い変更が必要
実装モジュール
ソフトウェアの前提に依存しない,独立したロジック部分?
ソフトウェアの前提条件はモジュールに対する引数として与えられる
他のソフトウェアでも再利用可能
それぞれを別のモジュールに実装し,分離することで実装モジュールの再利用性を保つ
インターフェースと実装の分離
モジュールはインターフェースと実装2の2つの部分からなる
インターフェース
モジュールが持つ機能を定義し,使用方法を定めるクラス
クライアントによってアクセス可能
実装
モジュールが持つ機能を実現しているコード部分
実装はクライアントからアクセスできないようにする
クライントからの使われ方(インターフェース)と機能の実現方法(実装)の独立性を保つことで,クライアントへ影響を及ぼさずに実装を変更することが可能になる
インターフェースを用いてコードを設計する
参照の一点性
モジュールの要素について宣言され
定義されるのは1回限りにする
変数の値を初期化したら以降は変更しない
値の変遷を追いかけなくて良いので読みやすい
副作用(ある処理が状態の変化を引き起こし,その後の処理の結果に影響を与える)のないプログラミングが可能になる
不要な可変性は排除してイミュータブルな変数を増やす
可変な変数のスコープは極力小さくする
参照透過性
呼び出しの結果が引数のみに依存する
呼び出しが他の機能の動作に影響を与えない
分割統治
大きな問題を小さくして各個撃破する
ソフトウェアの全体設計をする際には独立して設計できる部分に分割してから取り組む
モージュールを設計する際には 「責任・責務」の観点からモジュールを分割する
大量データ処理では計算を小さい単位に分割して分散環境で並行して実行できないか検討する
アーキテクチャ非機能要件
機能以外の要件6種類
変更容易性
相互運用性
効率性
信頼性
テスト容易性
再利用性
要件定義においてそれぞれの観点についてどの程度必要とされるのか考える
アーキテクチャ設計の時点でこの要件を考慮に入れた構造を考える
テストにおいて要件を満たしているか確認する
変更容易性
保守性
保守性を高めるために,変更を局所化し,他モジュールへの影響を最小化することを考える
拡張性
クライアントに影響を与えずにモジュールの交換を可能とする構造を考える
再構築
モジュール間の関係の変更,実装には影響を与えず柔軟に変更可能である必要がある
移植性
ハードウェア依存でなくする
相互運用性
他のソフトウェアと同じプロトコルを利用して相互に接続できること
ソフトウェアはシステムの一部であり,独立したものではない
標準規格を選択し,外部の機能やデータ構造へ,アクセスが明確に定義されたアーキテクチャを設計するよう心掛ける
効率性
時間効性
スループット
レスポンスタイム
ターンアラウンドタイム
資源効率性
CPU, メモリ, ストレージ,ネットワーク伝送量
信頼性
フォールトトレランス
障害が発生したときに正常な動作を保ち続ける能力
冗長化
アーキテクチャを二重化しておく
フェールソフト
障害発生時に大事な機能のみに絞って処理継続を優先する設計
ロバストネス
不正な使用方法や入力ミスからソフトウェアを保護する能力
フェールセーフ
障害時に障害発生部分を切り離す設計
フールプループ
予め,ユーザーが誤った操作を行っても安全に可動させる設計
テスト容易性
ソフトウェアのサイズと複雑性の増加に対して,効果的かつ効率的にテストを行える必要がある
効果的
テストによって隅々まで品質を検証できるか
効率的
テストのコストや労力が少ない
アーキテクチャ策定の時点から,検証方法の観点も含めて設計する.モジュール間の依存関係はなるべく排除する
再利用性
再利用するソフトウェア開発
すでに開発済みのソフトウェアを用いてできる限り新たなものを作らず開発を行う
実績のあるかれたモジュールを利用すれば全体の品質も向上する
既存モジュールを今回の開発目的に沿った使い方ができるようにするグルーコード(糊付けモジュール)を作成する
再利用のためのソフトウェア開発
将来のプロジェクトで再利用できるようなモジュールを現在のソフトウェア開発で創出する
変更を加えることなく,他のシステムで再利用できるようにする(独立してビルドできるようなモジュールないしパッケージにしておく)
難易度3倍の法則
一般化した再利用可能なモジュールを作るのは単一目的のケースに比べて3倍難しい
問題の一般化,処理の一般化,テストの一般化
テスト3種類の法則
再利用予定のモジュールがっできたら,最低限「3つ」の問題領域でテストする
実装時には想定できなかった問題が必ず出てくる
7つの設計原理
開発時に障害を作り込ま無いために作られた7つの経験則
コードレビュー時にチェック観点として使用する
共有することで,レビューそのものの品質を保つ
単純原理
シンプルにこだわる
シンプルで見通しのよいコードを心掛けると,障害は発生しない
無駄に複雑なコードを書きたくなる誘惑には気をつける
同型原理
形に拘る
同じことは同じように扱うことにこだわる
同一モジュールでは扱う数値の単位は統一する
引数の並び順,変数の使用順序を統一する
視覚的に異なる処理が目立つことで,障害に気づきやすくなる
独創性は抑制し,一貫性を優先する
対称原理
形の対称性にこだわる
ある処理についてその「対」になるものを考える
flag による条件分岐・・・?
命名の対称性 「set/get」「start/stop」etc
階層原理
構造が階層であることにこだわる
階層ごとに処理を取り決め,同じ種類の処理が異なる階層に渡らないようにする
リソースの獲得を行ったら,同じ階層でリソースの開放を行う
明確に表現された階層構造があると,読む人が全体を抽象化して理解することができる
必要に応じて
階層を上下することで必要な情報を効率的に理解できる
1つの階層は同じ抽象レベルのものだけで構成する
上位から見たときに下位レベルが「外部から見ている」視点で記述する ( 上位は下位の実装に依存しないようにする)
線形原理
処理の流れは直線であることにこだわる
制御構造が多いとコードがわかりにくくなる
階層の上位から海に向かって流れていく処理の流れを意識する
反復を避け,一筆書きできるようなシーケンスにする
処理の分岐を少なくし,特殊な振る舞いを主処理には混ぜない
複雑な各処理はサブ関数に隠すということ??
明証原理
ロジックの明証性にこだわる
明らかに正しいと言えるようにコードを書く
必要であればコメントや別途ドキュメントを作成する
コードは他人が読んで理解しやすい状態にしておくべき
明確なロジックを書き,読んだ人が疑問に思いそうな箇所にはコメントを残す
役割を想像できる変数名を用いる
安全原理
必然性のないところや曖昧な箇所は安全側に倒して設計・プログラミングしておく
ありえない条件をあえて考慮してコードを書く
様々なケースを想定して安全側に倒しておくことで事故を未然に防ぐ
仕様書には必要条件しか書かれていないことが多い
エラー処理等書かれていない条件を考慮した十分条件を満たすコードを書くには,機能と状況を正しく網羅して,ユーザーに確認しながら実装する必要がある
UNIX思想
UNIX文化の中で育まれた,経験に基づいた実践的な「技」の集合を明文化
1969年から今でもUNIXは使われ続けている
初期の設計判断の影響は大きい
モジュール化の原則
コードの中で関係性の高い要素を集めて,モジュールを作成する
モジュールのインターフェースはシンプルなものにする
モジュール間の関係性をシンプルにすることで,問題は局所化され,対称とするモジュールのみを変更することが可能になる
ソフトウェアはシンプルなモジュールの集合体として構築する
明確性の原則
保守コストを下げるために,コードは明確になるようにする
最低限,二度同じコードを解読しなければならなくなったらコメントを残す等の改善を行う
分離の原則
メカニズムからポリシーを分離する
ポリシー
ソフトウェアの置かれた前提に依存する部分
ビジネスロジックやUI
比較的不安定
メカニズム
ソフトウェアの置かれた前提に依存しない独立した部分
描画処理etc
比較的安定
安定な部分と不安定な部分を分けて管理することで
安定な部分の不要な変更を避ける
不安定な部分の柔軟性を維持する
安定な部分の再利用性を高める
サービス系アプリケーション
フロントエンド
通信プロトコルを理解し,クライアントからの要求を受け付ける
バックエンド
実際のサービスを行う
組み立て部品の原則
rule of composition
ソフトウェアは他のソフトウェアと見合わせることができるようにつくる
インターフェースはできる限りシンプルにすることで,連携相手について考えなくて済むようにする
バイナリデータよりも,シンプルなテキスト形式で入出力する
単純性の原則
すべての場合においてコードがシンプルにならないか検討する
複雑になる原因
技術を誇示しようとするプログラマの気持ち
機能に対する外部からの要求
対策
コードが膨れ上がり複雑化することを拒否し,単純な解決方法を評価する
機能を連動しあう小さな部品に分割する方法を探す
倹約の原則
コードの分量が多く複雑なコードは書かないようにする
まず小さなコードを書き,継ぎ足していく
大きくなったら分割を試みて,分割できない場合に限り大きなコードを残す
透明性の原理
ソフトウェアの動作を外部からわかりやすく見えるように設計する
透明性・開示性を意識して設計する
透明性
一見で「何をどのようにしているのか」が理解できる
開示性
ソフトウェアの内部状態につて監視ないし表示できること
デバッグのための機能を設計初期から組み込む
ログを盛り込む
モジュール内変数の内容を文字列化するメソッドを組み込む
安定性の原則
通常・予想外の条件下でも適切に動作させる
透明性と単純性を維持して,様々な条件に低コストで対応できるように維持しておくことが必要
透明性
コードを見通すことができて,何が起きているのかがすぐに分かる
単純性
コードで行われていることが複雑でなく,すべての分岐条件を難なく説明できる
安定していないソフトウェアはユーザーに提供する価値が著しく低い
不具合があっても,簡単に理解して修復できるように,透明で単純であることが重要
対策
コードレビュー
極端な入力に耐えられるか検証する
表現性の原則
コードにおける情報の表現方法は,ロジックではなくデータに寄せて書く
データ構造は複雑なものでも比較的理解しやすい
複数のスイッチ文よりも変換表(配列)等のほうがわかりやすい
データ・ロジックのどちらかを複雑にしなくてはいけないとしたら,迷わずデータを選ぶ
コードを改善する際は,コードの複雑さをデータの複雑さに変換することを検討する
驚き最小の法則
インターフェースはそれを使う人が想像するであろう形に設計する
ユーザーの理解にかかるコストを最小にする
よくにたソフトウェアのインターフェースをモデルにする
想定ユーザーの特徴を考慮する
伝統に注意を払う
「一見似ているが微妙に異なる」ということを避ける
沈黙の原則
不要な表示は最小限に抑える
ユーザーの注意や集中力のリソースは有限
出力が他のソフトウェアの入力になるときもあり,必要な情報がすぐわかるほうが良い
本当のエラーだけを標準エラー出力に表示
ログを残す際は,エラー,デバッグ用と分けて,必要なときにのみデバッグ用のものを出力する
表示されている情報がすべて重要なら,ユーザーは情報の仕分けの必要がなくなる
修復の原則
エラー発生時に回復に失敗したのであれば,以降の処理は直ちに停止するべき
エラーハンドリングがうまく行けばよいが,修復が成功せずに処理が継続されてしまうと最悪(データを壊し続けることになるかも)
エラーが発生した場合はけたたましく通知を出し,無理して処理を継続せずにユーザーに判断してもらう
経済性の原則
- 設備費用に比べて,プログラマの人件費のほうが比較にならないほど高価なことを意識する
プログラマの時間を浪費する要素
ハードウェアが貧弱
使用するソフトウェアに対する制限
環境に関するルールや制限
設備に投資して,プログラマが効率よく,気持ちよく仕事ができれば簡単に投資は回収できる
開発効率が上がり,ストレスは下がるので,生産性や品質が格段に向上する
ルールや制約は施行後にバランスを調整する
生成の原則
コードを生成するコードを書く
コードに対する手作業の単純作業はなくす
普段の作業を意識的に自動化する
人間は細かい仕事が苦手
繰り返しが多く,定型的なコードは生成の対象とする
最適化の原則
正しく動作するコードを描いてからコードを最適化する
早い段階での「速いコード」は設計を破綻させる
透明性や単純性が犠牲になる
コードが複雑になることで,障害のデバックにかかる時間に比べて遥かに価値の少ない微々たる高速化しか得られないことが多い
部分最適化が全体最適化の妨げになる
全体が見えていない段階で,半端に部分最適化すると,全体の最適化ができなくなる可能性がある
コードが正しく,単純であれば最適化する部分も探しやすい
プロトタイプを作ると,「コードを書かなくて済む」ことが分かる
多様性の原則
「唯一の正しい方法」は原理的にありえないので,常に多様性を認め,思考停止せずにより良いやり方を模索し続ける
人の想像力には限りがある,すべての面で最適なものが作れる人だとしても,すべての用途までは予測できない
1回のリリースでユーザーのすべての要望には答えられないし,そもそも要望自体が変化する
オープンで拡張性の高いソフトウェアにして相互運用性を高める
拡張性の原則
コードには成長の余地を残し,多様なニーズに応えながら成長させていく
最初の設計が将来に渡って完璧であることはありえない
ソフトウェアをプラガブルになるように設計し,それを明示する
拡張のための接続部分を柔軟なものにして,コードの中に「〜が必要になったら」というコメントを付与しておく
必要でない機能を追加するのではなく,必要になったときに機能を簡単に追加できるようにすることが大事
無駄な機能とコードを増やさない
UNIX哲学
UNIXの背後にある設計の哲学
設計哲学が優れており,普遍的だから現在でもUNIXは使われている
小ば美なり small is beautiful
ソフトウェアは小さく作り,小さく保つようにする
小さいソフトウェアは扱いやすい
理解が容易
保守が容易
マシンリソースに負担をかけない
他のソフトウェアと組み合わせやすい
大きなソフトウェアは扱いづらい
複雑でコードの理解が困難
いくら複雑にしても1つの大きなソフトウェアでは不測の事態に対応できない
コードは小さなものから始めて小さなままに保つ
小さく設計して人1つの仕事に専念する・機能が足りなければ他のソフトウェアと連携することを考える
解決する問題をきちんと理解し,必要なコードだけを書く
1つ1仕事
1つのソフトウェアには1つのことをうまくやらせる
1つの仕事に集中することでコードから不要な部分が消える
1つの仕事に集中することで,実装時にその仕事の本質を掴むことができる
1つのことのみを行うソフトウェアは再利用しやすい
実現のために
問題が大きかったら分割し,核問題に対応する小さなソフトウェアを作成する
問題が拡張していった場合には別々のソフトウェアを組み合わせることで対応する -> スパゲッティコードを回避する
即プロトタイプ
できるだけ早くプロトタイプを作成し,検証する
最初から完全なソフトウェアを書くことは不可能, 試行錯誤を繰り返して継続的な改善が必要
目に見える形でゴールを示し,メンバー全員のイメージを合わせることでプロジェクトを前進させる
前提の誤りを早期に発見できる
要件不備による手戻りを減らせる
早いうちから誤りを取り除く作業を始められる
効率性より移植性
2択で迷った場合は移植性を取るべき
ハードウェアの価値に依存しないためにも,ソフトウェアには移植性が求められる
移植性を持たせるために開発効率性を下げても後で十分に報われる
対策
ハードウェアに依存する部分と依存しない部分を切り離した設計を行う
依存しない部分は再利用しやすい単位でモジュール化する
ハードウェア専用の能力を使用することになるような最適化は避ける
データはテキストで保存する
Store numerical data in flat ascii fie
データの移植性の解がテキストファイル
最も一般的で移植性が高い形式
人間がデータをすぐに閲覧・確認可能
ツーツやコマンドが扱いやすい
レバレッジ・ソフトウェア
Use software leverage to your advantage
既存のソフトウェアを活用し,開発を効率化する
コードを大量に書く一番の方法は,借りてくること ( 高ROI)
単機能を持つソフトウェアをグルー言語でつなげることで大きな仕事おを成し遂げる
手作業を自動化することで正確性や生産性を劇的に上げる!
特に考えることなく手作業を繰り返してはいけない
シェルスクリプト活用
シェルスクリプトを用いることで,レバレッジを効かせつつ移植性を高める
シェルスクリプトはインタープリタ言語で,プラットフォーム専用のバイナリにコンパイルする必要がない
シェルスクリプトをグルー言語として複数の小さなソフトウェアをつなげると良い
過度の対話インターフェースを回避
ソフトウェアごとの独自の対話方法を覚えなければならない
ソフトウェア同士が対話できなくなる
待ち時間が多くなる (プログラムの)
入力部分の解析コードが大きく,見にくくなる
ソフトウェア同士の対話が減るため,一つのソフトウェアに機能が集中する
ソフトウェアの会話の相手はソフトウェアを中心に考える
フィルタ化
すべてのソフトウェアを「入力ストリームとしてデータを受け取り,何らかの加工を施し,加工したデータを出力ストリームに送り出す」フィルタとして設計する
ソフトウェアの本質はデータを「処理」することで「生成」することではない(データの生成は人間が行う)
データの入出力には標準入出力を使用することでソフトウェアを接続可能にする
1 前提
ソフトウェアは本質的に困難
複雑性: 規模が大きくなるほど構造の依存性は非線形に増す
同調性: ソフトウェアは複雑な実世界に同調し続けなくて背景ない
可変性: ソフトウェアが世界に影響を及ぼせばまた,要求も変わりそれに答えなくてはいけない
不可視性:ソフトウェアは概念の集積であり目には見えない,プロセス,意思決定の経緯も見えない
プログラミングは設計
創造的な高位であり,使用をコードに符号化するだけのルーチンワークではない
基本設計・詳細設計・プログラミング・テスト・デバッグは不可分な作業であり,分担するのはうまいやり方ではない
コードはできるだけ早く書き上げて不明確な部分をなくすべき(アジャイル)
コードは必ず修正される
変更に強いコードを書く
読みやすいコードを書く,書く時間よりも読まれる時間のほうが圧倒的に長い
4. 視点
プログラマの見る角度
凝集度
凝集度
モジュールに含まれている機能の純粋さを表す尺度
7段階あり,数字が大きいほど強く,よいモジュール
コードはモジュールに分割し,モジュール間は独立していることが重要
「モジュール内」の関連性を最大化し,「モジュール間」の関連性を最小化する
モジュール内での関連性のメトリクスとして,モジュール自身の関連性の強さを測るのが「凝集度」
凝集度が高いモジュールは構成要素の関係性が高く,限定された目的に特化している
設計の明確さと理科雨の視やすさが高い
保守と拡張が容易になる
再利用性が促進される
モジュール間の疎結合も促進される
結合度
結合度
モジュール同士の関係の密接さを表す尺度
6 段階あり,数字が大きいほど歓喜会が薄く,疎結合であり良いモジュールであるとされる
結合度の判定は,モジュール間でデータがどの様に受け渡しされているかに着目