良いコード/悪いコードで学ぶ設計入門
―保守しやすい 成長し続けるコードの書き方
https://gyazo.com/dae43fc1b46077da9a35e7ae854414d1
第1章 悪しき構造の弊害を知覚する
変更容易性を高める設計
第2章 設計の初歩
変数を使いまわさない。目的ごとの変数を用意しよう
カプセル化とは、データとそのデータを操作するロジックを一つにまとめること
第3章 カプセル化の基礎-一つにまとめる-
変更容易性を高める設計には、以下の三つが重要な基礎
カプセル化
関心の分離
多態性による機能の取り替え
必ずクラスのインスタンス変数を操作するように実装する
https://gyazo.com/59e88b759f6b26d9df2788f5e9070fa8
https://gyazo.com/09f1245f6e4ef671d527caf363474ee6
yana-gi.iconこの2つの図わかりやすい
生焼けオブジェクト(インスタンス生成後にインスタンス変数に代入して初期化したオブジェクト)を防ぐためにはクラスのインスタンスを生成する時点で、インスタンス変数に正常値が確実に設定されている状態にする(完全コンストラクタ)
yana-gi.iconrailsだとvalidateがあるからイニシャライザではあまり異常値エラー書かないな
インスタンス変数の上書きはせず、不変な値にする
yana-gi.iconrubyだと.freeze
変更したい場合は新しいインスタンスを作成する
値の渡し間違いを型で防止する
プリミティブ型ではなく独自の型を引数に設定する
code:java
// bad
final int ticetCount = 3;
money.add(ticketCount); // チケット枚数をmoneyにaddできてしまう
//good
class Money {
Money add(final Money other) { // 引数をint→Money
final int added = amount + other.amount;
return new Money(added, currency) // 新しいオブジェクトを返す
}
}
メソッド引数やローカル変数も不変にする
バグはデータに不正な値が混入することで発生する
yana-gi.icon言われてみればそうなんだけど、この意識あまりなかったな
クラス設計とは、完全性を保証するしくみづくりといっても過言ではありません
設計パターン(デザインパターン)の中の完全コンストラクタと値オブジェクトはカプセル化の基本 第4章 普遍の活用ー安定動作を構築するー
可変(ミュータブル)と不変(イミュータブル)
デフォルトは不変にする
どんなときに可変にしていいか
パフォーマンス要件を満たせない時
スコープが局所的なケース(ループカウンタなど)
第5章 バラバラなデータとロジックをカプセル化する実践技法
プリミティブ型(int,bookean,floatなど)
プリミティブ型を濫用したコードをプリミティブ型執着と呼ぶ
重複コードや演算ロジックが実装されやすい
データがただ存在しているだけ、というのはほとんどありえません。 データを使って計算したり、データを判断して制御を切り替えたりするものです。プリミティブ型だけで実装しようとすると、データのありかとデータを使って制御するロジックのありかがバラバラになります。
引数が多い場合は、データを引数として扱うのではなくそのデータをインスタンス引数として持つクラスへ設計を変更してみる
デメテルの法則
知らない人に話しかけるな(利用する内部のオブジェクトを知るべきではない)
尋ねるな、命じろ
第6章 関心の分離という考え方ー分けて整理するー
インターフェイスと実装を分離して考える
インターフェイス
取得したい結果
結果の取得に必要な入力
実装
インターフェイスの仕様を満たすように実装する
ロジックを利用する側と利用される側の視点の違い意識する
利用する側は詳細な実装は知らなくてよい
第7章 関心が混ざったコードを分けて整理する実践技法
単一責任の原則
クラスが担う責任はたった一つに限定すべき
DRY原則
△ コードの重複を許すな
全ての知識はシステム内において単一、かつ明確な、そして信頼できる表現になっていなければならない。
達人プログラマーより
同じようなロジック、似ているロジックであっても、目的が違うロジックは共通化してはいけない
🙆 頻度の観点ではなく、目的が同じかで共通化する
継承はよっぽど注意して扱わないと危険。継承は非推奨
yana-gi.iconそういう認識はあるが、なぜ危険なのかはわかっていない
サブクラスはスーパークラスの構造に依存する
→スーパークラスの動向に注意する必要がある
継承(is-a)より委譲(has-a)
コンポジション構造(クラスないでインスタンスを生成する、has-aの関係にする)
第8章 条件分岐―迷宮化した分岐処理を解きほぐす技法―
ストラテジパターン
interfaceを使ってまとめて機能を取り替える設計