新装版 リファクタリング ~既存のコードを安全に改善する~
- 読みました。
- 忘れないうちに、それぞれの手法について一言くらいでメモしていきます。
新装版 リファクタリング―既存のコードを安全に改善する― (OBJECT TECHNOLOGY SERIES) Martin Fowler 児玉 公信 オーム社 2014-07-26 売り上げランキング : 22428 Amazonで詳しく見る by G-Tools |
第8章 データの再構成
自己カプセル化フィールド
- Getter/Setter のこと
- コンストラクタで設定するfinalだけのクラス(VOとか)は正直なくていい
オブジェクトによるデータ値の置き換え
-
string
とかint
とかもできるだけ色つけて振る舞い持たせる
値から参照への変更 / 参照から値への変更
- 実体がひとつかどうかで判断する
オブジェクトによる配列の置き換え
- 配列の中身に、異なる意味合いをもつ値をいれるのはダメ
- 名前、体重、身長...とか
- まずやらない
観察されるデータの複製
- 階層が違ったり、異なるクラスだけど取り扱うデータは同期したい場合
- Observerパターンを使う
単方向関連の双方向への変更 / 双方向関連の単方向への変更
- 相手を保持し、相手に自分を保持するよう指示する
- 1対多対応で参照し合う場合は、参照を1つ持つ側が主
- コンポジションの場合は集約元が主
- 多対多の場合はどっちでも良い
シンボリック定数によるマジックナンバーの置き換え
- よくやる
SOME_CONSTANT
ってやつ
フィールドのカプセル化
- フィールドは基本隠蔽する
- メソッドでアクセスする
コレクションのカプセル化
- コレクション本体をget/setさせない
- 渡した先でどう扱われるかコントロールできなくなる
public ArrayList<String> getList() {
return this.List; // NG
}
データクラスによるレコードの置き換え
- 構造体をクラスで置き換えるよって話
- 不要
クラスによるタイプコードの置き換え
- enumを使おう
サブクラスによるタイプコードの置き換え
- enumを使おう
State/Strategyによるタイプコードの置き換え
- アルゴリズムの取り替えをしたい -> Strategy
- 状態が変わる(状態によって処理が変わる) -> State
フィールドによるサブクラスの置き換え
- サブクラスを分けているけど返す定数が違うだけ、の場合はフィールドで済ます
第9章 条件記述の単純化
条件記述の分解
- 条件式の判定、{}内の処理それぞれメソッドとして抽出して適切な名前をつける
条件記述の統合
- 処理が同じ分岐は統合する
- 条件式をメソッドで置き換えて適切な名前をつける
重複した条件記述の断片の統合
- 同じコードが複数の分岐内に散在するときはまとめる
制御フラグの削除
- return したり break したりで回避する
ガード節による入れ子条件の置き換え
- メイン処理を本流とする
- 頻度の低い処理、例外的な処理はガード節で書いて、早期リターン
ポリモーフィズムによる条件記述の置き換え
- オブジェクトの種類によって処理が違う場合
- ×オブジェクトの種類判定 -> 処理を変更
- ◯そもそもオブジェクトに処理をもたせる
ヌルオブジェクトの導入
- インターフェースは実装するけど何もしないオブジェクト(NullCustomerとか)をつくる
- 空の場合のチェック・条件分岐とかを回避できる
表明の導入
- エラーとアサーションは明確に分ける
- アサーション
- 前提条件の確認
- 本来は呼び出し側で実施すべきもの
- ドキュメントなどに表現される
- 開発段階では、前提条件に合わない場合はエラーとしたい(開発者の効率のため)
- 稼働段階では、条件判定したくない(パフォーマンスを下げる要因になるため)
- とにかく開発者のためのチェック
- エラー
- ユーザー入力の値、アプリの内部状態、タイミング次第で起きうる事象
- 続行すると問題が発生する場合
- 開発段階でも稼働段階でもチェックしなければいけないもの