A Philosophy of Software Design の感想やまとめ
/icons/hr.icon
複雑性
複雑性とどうやって戦うか
複雑とは
ソフトウェアシステムの構造に関するもの
システムの理解・修正を難しくするもの
複雑さを決めるのは、書き手ではなく読み手
どんなに大規模でも、理解が容易で修正が簡単なら、複雑ではなく単純
複雑性の影響
変更の増大
認知的負荷
未知の増加
優れた設計の最も重要な目標の1つはシステムが明白であること
複雑性の原因
依存性
不明瞭性
複雑性への立ち向かい方
複雑性の排除
複雑性の隠蔽(カプセル化)
複雑性は小さな塊が積み重なって起きる
/icons/hr.icon
戦略 vs 戦術
戦術(tactical)
とりあえず動けば良いというアプローチ
リファクタリングよりも、次の機能を作る方が大事
早いが負債を残した状態で進むため、いつかは問題が発生する
戦略(strategy)
重要なのは長期目線でのスピードアップ
/icons/hr.icon
モジュール
複雑性対処のためのアプローチの1つ隠蔽として、モジュールを扱う
モジュールの分割
インターフェースと実装の分離
優れたモジュールは強力な機能とシンプルなインタフェースを併せ持つ
Deep Module と呼ぶ
Deep Module とは反対に Shallow Module がある
Shallow Module は、提供機能に対してインターフェースが複雑なものを指す
/icons/hr.icon
情報隠蔽と情報漏れ
情報隠蔽(Deep Module)
インターフェースをシンプルにすることで複雑さを隠蔽する
モジュール以外に依存関係をなくすことで進化を容易にする
情報漏れ
ある設計の変更が複数のモジュールに波及する
/icons/hr.icon
モジュールはある程度、汎用的にすべき
シンプルで深いインターフェースを実現できるようにある程度汎用化する方が好ましいと著者は言っている
/icons/hr.icon
異なるレイヤーでは、異なる抽象化をする
異なる抽象化の例としてネットワークプロトコルがある
最上位レイヤーでは、バイトストリームの送受信を扱う
下レイヤーでは、パケット部なkつして転送を実現するレイヤーがある
Decorator パターンは Shallow Module になりがちなので利用は好ましくない
なので、新しい機能をベースクラスに追加や独立したクラスにする方が良い
/icons/hr.icon
複雑性を下位におしやる
複雑さがモジュール提供機能と関連するならモジュール内部で対応すべき
/icons/hr.icon
同じとこに実装する or 分けて実装する
重要なのは複雑性の軽減
細分化すればするほどすべてのパーツの把握が困難&パーツを繋ぎ合わせるコードが増える
パーツが本当に独立しているのであれば分割は良いこと
分割有無の指針
情報が共有される場合はまとめる
インターフェースをシンプルにできるならまとめる
/icons/hr.icon
例外をそもそもなくす
例外は複雑さを増大させる
正常コードより本質的に書くのが難しい
例外処理はさらなる例外を引き起こす
例外処理コードの動作確認は難しい
そもそも例外を使うべきか考える
/icons/hr.icon
Design it Twice
ソフトウェアの設計はそもそも難しい
オプションを複数設計して、長所・短所をリストアップして選んだほうがうまくいことが多い
/icons/hr.icon
なぜコメントを書くのか
コメント・ドキュメントには抽象化という役割がある
コメントを書かない4つの言い訳
Good Code is self-documenting
コメント書く時間がない
コメントが古くなってむしろミスリード
これまで見てきたコメントは無価値だった
これらの言い訳は良くない。
コメントは抽象化の基本で、抽象化の目的は複雑さの隠蔽を行うこと
コードだけでは表現できないものをコメントとして残す
良いコメントは保守性を担保する
/icons/hr.icon
原則:コードから明らかでないことをコメントに書く
コメントはシンプルで上位の視点を与えてくれる
良いコメントを書くために
規約を選ぶ
コードと同じことを書かない
/icons/hr.icon
命名
良い名前は可読性を高める
一方で悪い名前は複雑さ・曖昧さによりバグの原因になる
良い名前は「正確性」と「一貫性」の2つの性質がある
一方で悪い名前に多いのは「一般的すぎる」or「曖昧すぎる」ことが挙げられる
/icons/hr.icon
実装する前にコメントを書く
コメントを設計プロセスに組み込む
Comment First Process
/icons/hr.icon
既存コードの保守・メンテナンスにおいて戦略的であり続ける
ただし、商用コードでは時間との戦いがあるので、妥協せざる得ない時がある。
妥協にはできるだけ抵抗すべし
コメントをコードの近くに置く
既存のコードを変更すると、コメントの一部が無効になることがあるので、近くに配置して気づきやすくする
コメントはコミットログではなくコードに書く
コミットメッセージはリポジトリ内で検索可能
開発者が最も目にする可能性の高い場所にドキュメントを配置する
/icons/hr.icon
一貫性
一貫性は複雑性の低減に寄与する
一貫性を確保するアプローチ
ドキュメント化
Linter の導入
プロジェクトのルールに従う
/icons/hr.icon
コードは理解しやすくあるべき
理解しやすさは読み手が判断する
コードレビュー
理解しやすくするためのテクニック
適切な空白を入れる
イベントドリブンなコードには、ハンドラが発火するタイミングをコメントで書く
ほかにもある
/icons/hr.icon
ソフトウェアトレンド
OOP
アジャイル開発
インクリメンタルな開発では「抽象の必要に気づいたら、時間をかけるのではなく一気に設計する」ことが大事
機能をインクリメントして作っていく中で抽象を作るのではない
ユニットテスト
TDD
デザインパターン
過剰適応は最大のリスク
getter & setter
インターフェースを乱雑にする要因になるので、できれば避けたい
/icons/hr.icon
パフォーマンス向けの設計
性能に関する基本的な知識を用いて「自然に性能が出て」「クリーンでシンプル」なデザインを選択する
そのため、何がコストが高いか知っておく
修正前に計測もする
参考