書物の紹介
良いコード/悪いコードで学ぶ設計入門 ―保守しやすい 成長し続けるコードの書き方
ITエンジニア本大賞2023で大賞に選ばれた本です。
感想としては、様々な基本的な知識を現代の状況に折り合いをつけてまとめた良書だと思います。
重要ポイントのみをまとめましたが、購入して読んでみるとより理解が深まると思います。
第1章 悪しき構造の弊害を知覚する
■悪しきコードとは
- コードを読み解くのに時間がかかる
- バグを埋め込みやすくなる
- 悪しき構造がさらに悪しき構造を誘発する
- 低凝集、生焼けオブジェクトにならない
■重要なワード
- 低凝集
- 関連するデーやロジック同士が分散し、バラバラになっていること
- 生焼けオブジェクト
- 初期化しないと使い物にならないクラス、または未初期化状態が発生しうるクラス
第2章 設計の初歩
- 変数、メソッド、クラス名はなるべく内容を把握できるようにする
- 名前について理解不能な連番や省略形はダメ
- 簡素なメソッド内の変数などは許容と思われる
- 変数の使いまわしは避ける
- メソッドは意味のあるまとまりでメソッド化
- 関係し合うデータとロジックをクラスにまとめる
第3章 クラス設計
- クラス単体で正常動作するように設計する
- コンストラクタで正常値を渡すように確認を行う
- 計算ロジックはデータ側に持たせる
- 不変(final)で思わぬ動作を防ぐ
- 変更したい場合は新しいインスタンスを生成する
- 値の受け渡しを型で防止する
■重要なワード
- 完全コンストラクタ
- インスタンス変数を全て初期化できるだけの引数を持ったコンストラクタ
- コンストラクタ内では、ガード節で不正値を弾きます
- 値オブジェクト
- 値をクラスとして表現する設計パターン
- クラス化することで値に関するロジックを追加することもできる
第4章 不変の活用 - 安定動作を構築する -
■再代入はしない
- それぞれの値の変数をちゃんと用意する
- イミュータブルでそれを防ぐ
- 引数も不変にする
第5章 低凝集 - バラバラになったモノたち -
- staticメソッドはログ出力やフォーマット変換など、凝集度に影響のないものにする
- コンストラクタをprivateにして用途を絞る
- ファクトリメソッドをstaticで作成して作成用途を限定する
- 用途不明で汎用的な名前は使わない
- CommonとかUtilとかではなく、具体名をつけて
- 結果を返す引数は使わない
- 多すぎる引数は使わない
■重要なワード
- 尋ねるな命じろ
- 他のオブジェクトの変数などを訪ねたり、その状態によって呼び出し側が判断するのではなくて、呼び出し側は命ずるだけで、判断や制御は命じられた側がやる
第6章 条件分岐 - 迷宮化した分岐処理を解きほぐす技法 -
- 早期returnでネスト解消
■ストラテジパターン(interfaceをswitch文重複に応用)の例
- 魔法interfaceを作成する
- interfaceを継承して各魔法クラスを作成する
- listに魔法をクラスを登録してswitch文やfor文で制御できるようにする
■ポリシーパターン(ルールを制御するクラスを作成して制御する)の例
- ルールinterfaceを作成して、okメソッドを作る
- 購入ルールクラス、返品率ルールなどのクラスをinterfaceを継承して作成する
- ポリシークラスを作成して、ルールinterfaceを継承したクラスをaddできるようにする
- ポリシークラス内で特定ユーザーのルールが全て満たしているか一括で確認できる(okメソッドを呼び出す)
第7章 コレクション - ネストを解消する構造化技法 -
- 標準のリスト機能で検索を容易にする
- コレクションをカプセル化して不正状態などを防ぐ
- 外部に渡すときは変更できないようにする
第8章 密結合 - 絡まってときほぐせない構造 -
-
継承はよっぽど注意して扱わないと危険、継承は推奨しない
-
継承よりコンポジション構造を推奨
-
なんでもPublicは密結合
-
コンポジション構造(クラス内に汎用的な別クラスのインスタンスを生成して、処理を容易にする)の例
- 武器効果クラスを作成
- 攻撃クラスのインスタンスを武器効果クラス内部に生成
- 攻撃値を取得するには攻撃クラスの攻撃メソッドに武器特有の効果をプラスする
■重要なワード
- 凝集度
- データとロジックの関係性の強さを表す指標
- 高い方が良い
- 結合度
- モジュール間の依存の度合いを表す指標
- 低い方が良い
- 密結合
- あるクラスが、他の多くのクラスに依存している構造
- 単一責任の原則
- クラスが担う責任は、たった一つに限定すべき
- 疎結合高凝集
- 疎結合且つ、高凝集な状態のこと
- 高凝集を意図して強く関係していそうなロジックを一箇所にまとめ上げようとしたものの、結果として密結合に陥っているケースがあるので疎結合高凝集な設計を意識する
- トランザクションスクリプトパターン
- メソッド内に一連の処理手順がダラダラと長く書き連ねられている構造
- 神クラス
- あらゆる責務のロジックが乱雑に絡み合うように描き殴られているクラス
第9章 設計の健全性をそこなうさまざまな悪魔たち
- デッドコードは作らない
- YAGNI原則は守る
- マジックナンバーは作らない
- 文字列型に執着しない
- グローバル変数は扱いに気をつける
- nullは扱いに気をつける
- 例外は握り潰さない
- メタプログラミングには気をつける
- パッケージの区切り方はビジネス概念の種類によって分ける
- コピペは気をつける
- プログラミングに銀の弾丸はない!
■重要なワード
- デッドコード
- 到達不能コード
- YAGNI原則
- You aren't going to need it(必要ないでしょう)の略
- 先回りして必要かもしれないコードは作らないでおく
- マジックナンバー
- 開発者にしかわからない数字
- メタプログラミング
- プログラムの構造自体を制御するプログラミング
第10章 名前設計 - あるべき構造を見破る名前 -
- 可能な限り具体的で、意味範囲が狭い、特化した名前を選ぶ
- 存在ベースではなく、目的ベースで名前を考える
- どんな関心ごとがあるか分析する
- 声に出して話してみる
- 利用規約を読んでみる
- 違う名前に置き換えられないか検討する
- 疎結合高凝集になっているか検討する
■重要なワード
- ラバーダッキング
- 誰かに説明すると自ら原因に気づき、自己解決する方法
第11章 コメント - 保守と変更の正確性を高める書き方 -
- ロジック変更時、同時に必ずコメントも変更すること
- ロジックの内容をなぞるだけのコメントをしないこと
- 可読性の悪いロジックを細く説明するようなコメントをしないこと。
- 代わりにロジックの可読性を高めること。
- ロジックの意図や仕様変更時の注意点をコメントすること
第12章 メソッド(関数) - 良きクラスには良きメソッドあり -
- 必ず自身のクラスのインスタンス変数を使うこと
- 不変をベースに予期せぬ動作を防ぐ関数にすること
- 尋ねるな、命じろ
- コマンド・クエリ分離
- 引数
- 引数は不変にすること
- フラグ引数は使わない
- nullを渡さない
- 出力引数は使わない
- 引数は可能な限り少なく
- 戻り値
- 型を使って戻り値の意図を表明すること
- エラーは戻り値で返さない、例外をスローすること
第13章 モデリング - クラス設計の土台 -
- 目的別にモデリングする
- 目的駆動で名前設計することが、適切に目的達成するモデル設計につながる
- 単一責任とは単一目的
第14章 リファクタリング - 既存コードを成長に導く技 -
■リファクタリングの流れ
- ネストを解消する
- 意味のあるロジックでまとめる
- 条件を読みやすくする
- ベタ書きロジックを目的を表すメソッドに置き換える
- ユニットテストでリファクタリングのミスを防ぐ
■リファクタリングで注意すべきこと
- 機能追加とリファクタリングを同時にやらない
- スモールステップで実地する
- 無駄な仕様は削除することも視野
第15章 設計の意義と設計への向き合い方
- 設計しないと開発生産性が低下する
- 後に大きな損失
■重要なワード
- 木こりのジレンマ
- 刃を研ぐ時間が作れずに、効率悪く木を切り続ける
- 循環的複雑度
- コードの構造的な複雑さを示す指標
- マジカルナンバー4
- 人間の短期記憶は一度に4±1個
- パレートの法則(80:20の法則)
- ソフトウェアの処理時間の内80%は、ソースコードの全体の2割の部分が占めている
- コアドメイン
- サービスの売りになるビジネス領域
- ドメインエキスパート
- サービスの事業領域に関して深い知識を持っている人
第16章 設計を防げる開発プロセスとの闘い
■設計
- 「早く終わらせたい」心理が品質低下の罠
- 粗悪なコードはきれいなコードを書くより常に遅い
- 厳密に設計しすぎず、サイクルを回し続けるのがコツ
- 設計ルールを多数決で決めるとコード品質は最低になる
- スキルの高いメンバーでつくる
■実装
- 少しずつで良いので気づいた箇所を改善する癖をつける
- 既存コードを信用せず、冷静に正体を見破る
- コーディング規約を利用する
■レビュー
- レビューを仕組化する
- 設計視点でレビューする
- 敬意と礼儀を持つ
■チームの設計力を高める
- 影響力を持つレベルまで仲間を集める
- 基本はスモールステップ
- 実感が大事、手を動かす
- フォローアップ勉強会を開く
- 勉強会のやり方は工夫し、徐々に物事を浸透させる
- リーダーやマネージャーに設計と費用対効果の話をする
- 設計責任者を立てる
■重要なワード
- コンウェイの法則
- システムの構造が、それを設計する組織構造に似てくるという法則
- 心理的安全性
- 自分の発言することを恥じたり、拒絶されるなど、不利益を被ることがないことをチームで共有されている心理状態
- アンカリング効果
- 最初に提示された数値や情報が基準になってしまい、その後の判断を歪めてしまう認知バイアス
第17章 設計技術の理解の深め方
■技術書紹介
- 現場で役立つシステム設計の原則~変更を楽で安全にするオブジェクト指向の実践技法
- リーダブルコード - より良い小オードを書くためのシンプルで実践的なテクニック
- リファクタリング 既存のコードを安全に改善する
- Clean Code アジャイルソフトウェア達人の技
- レガシーコード改善ガイド
- レガシーソフトウェア改善ガイド
- レガシーコードからの脱却 - ソフトウェアの寿命を延ばし価値を高める9つのプラクティス
- エンジニアリング組織論への招待~不確実性の向き合う思考と組織のリファクタリング
- プリンシプル オブ プログラミング 3年目までに身に着けたい一生役立つ101の原理原則
- Ceaan Architecture 達人に学ぶソフトウェアの構造と設計
- エリック・エヴァンスのドメイン駆動設計
- セキュア・バイ・デザイン 安全なソフトウェア設計
- ドメイン駆動設計入門 ボトムアップでわかる!ドメイン駆動設計の基本
- ドメイン駆動設計 モデリング/実装ガイド
- ドメイン駆動設計 サンプルコード&FAQ
- テスト駆動開発
■設計スキルを高める学び方
- インプットは2、アプトプットは8
- 設計効果を必ず意識すること
- リファクタリングで大幅スキルアップ
- 設計技術書でさらなる高みを目指そう