レガシーコード改善ガイド16章〜20章
16 章変更できるほど十分に私はコードを理解していません。
目的:コードを理解する。
結論:スケッチやメモなどのローテクを使う。それかコードをいじる
メモを取る・スケッチを描く
丸や線でクラスの関連性や影響などを書き出すとよい。案外精神状態をよくしてくれる。
印刷して印をつける
* 責務の分割
* メソッドの構造の理解→ブロックやインデントに線を引く
* メソッドの抽出→抽出部分をまるで囲う
* 変更の影響の理解→変更により影響を受ける変数をマーク
試行リファクタリング
バージョン管理されている実際にリファクタリングして、捨てる。
不要なコードを削除する
無駄な所に理解しようとする体力を使わない。
17 章私のアプリケーションには構造がありません
目的:システムの構造を理解するための手法を学ぶ
結論:システムのストーリーを話すと不自然な所がみつかる。そこをリファクタする。
システムのストーリーを話す。
1.簡潔にシステムを説明する。(→詳細を隠す)
コンセプトを2つや3つで説明しきる。そうするとシステムの責務がわかる。
2.機能の変更・追加を行う際に、説明に加えてみる。
違和感や本質から遠ざかってないかを確認する。
白紙のCRC
CRCとは(Class Responsibility Collaboration)の略
クラスのインスタンスをテーブルの上に並べて相互作用を確認する。
頭の中で考えてることをテーブルの上に再現する←超重要
ガイドライン
・カードはクラスではなく、インスタンスを示す
・コレクションはカードを重ねて表現する
会話の吟味
難題な作業に手いっぱいになると、しばしば別のアイディアを見落とす。
アイディアとコードにギャップがある場合、その理由を考えることが重要。
たいていは設計を理解できていないか、設計を勘違いしている。
18.自分のテストコードが邪魔になっています。
目的:テストコードの管理方法について
結論:命名規則やディレクトリ構造をうまく使う。
パッケージ的に同じディレクトリにしておくと恩恵は受けられる。
テストを配布しないケースでは、別ディレクトリにするのも良い。
デプロイコードにはテストコードは含めない
Mavenプロジェクト
デプロイコードにはテストコードは含めない
19.私のプロジェクトはオブジェクト指向ではありませんがどうすれば安全に変更できるでしょうか。
目的:タイトル通り。
結論:絞り込み点をみつけて、依存関係を排除してテストをかく。
また、新しい振る舞いの追加の際は、
データを生成するメソッドとそれをハンドリングするメソッドを分け、前者をテストすれば良い設計になって行く。
コマンドクエリー分離原則
20.このクラスは大きすぎて、もうこれ以上大きくしたくありません。
目的:クラスが大きすぎる時、小さくわけよう。その分け方を学ぶ
結論:クラスの中の結合度が高いクラスタでクラスを考え、低い所で分離を考える
1.単一責務の原則でクラスをわける。
2.メソッド名で機能を分ける
3.機能スケッチを行う。
メンバ変数をリストアップ
メンバ変数にアクセスするメソッドから矢印をひく。
コンストラクタは省略。
もっとも依存性が少ないポイントこそが絞り込み点。
そこを元にクラスをわける。
クラスの命名には一言でそのクラスの責務を説明すると思い浮かぶかも。
単一責務の原則への違反
2つ
インタフェースレベルの違反
1つのインタフェースが多くのメソッドに責任を持つ。1つのクラスで全てのメソッドを使うことは滅多にない。
これは、インタフェースを分けるのが理想的。、
実装レベルの違反
実装しまくっているか、委譲しまくっているか。→委譲している場合Facadeとみなすこともできなくもない。詳しくは要勉強
特定のクライアントに対してインタフェースを準備する
その部分の実装を切り離すことができれば、元のクラスは軽くなる。
戦術
単一責務は実装レベルで導入しておくと、インタフェース抽出も楽。
モンスターからインタフェースを抽出するのは作業量が必要。
クラス抽出の手法を決める要因
・影響を受けるメソッドのテストを簡単に用意できるか?
小さく分けるとコンフリクトが起きないので不本意なバグを埋め込む心配も減らせる