どういうことか?
リファクタリングにはいつ行うべきかに関しては、かっちりとした定義がありません。
そのため、「こういう現象が起きていたら怪しい。」「こういう現象が起きないようにプログラミングする」という指針を持つことが幸せなエンジニアライフを送る鍵になりそうです。
ということで、以下に本書で提示されているコードの不吉な臭い(避けるべきコードの書き方)を列挙していきます。
ランキング
1. 重複したコード
2. 長すぎるメソッド
3. 巨大なクラス
4. 長すぎるパラメータリスト
5. 変更の偏り
一つのクラスが別々の理由でなんども変更されてしまう状況のこと。
例えばDBを変更するたびにこの3つのメソッドを毎回修正している。さらに金融商品を追加するたびに、毎回この4つのメソッドを変更している。ということが同一クラス内で起きているのであれば、それは別々のメソッドに切り出すべきです。一つの変更に対して一つのクラスが対応するようにした方がいいです。
6. 変更の分散
一つの変更で、あちこち改修する必要がある状況のこと。
例えば階級によって給与を算出するメソッドがあるとします。switch文で対応する階級ごとの給与算出方法をクライアント側で実装しているとします。この時階級を一つ追加することになったとします。この時変更対象となるのは、クライアントとその階級を管理しているクラスです。なので、一つの変更が複数に波及してしまっていますね。これは、ポリモーフィズムを使えばクラスを一つ追加するだけで済みそうです。
7. 特製の横恋慕
オブジェクト指向には、処理及び処理に必要なデータを一つにまとめてしまうという重要な思想があります。ある処理を行うために、他のクラスに対してgetメソッドをたくさん投げていたら怪しいです。
ただし、このオブジェクト指向の原則に当てはまらないパターンもいくつかあります。その場合の解決策はGoFのStrategyとVisitorパターンがあります。振る舞いを別のクラスとして管理することができるので、振る舞いに対する変更を一つのクラスで吸収できるという利点がある反面、複雑になりがちです。
8. データの群れ
クラスのフィールドやメソッドの引数として頻繁にセットとなって現れるデータたちのことです。それらを見たら、フィールドの場合はクラスを定義することを、メソッドの引数の場合はパラメータオブジェクトを導入することを考えるべきです。
9. 基本データ型への執着
基本データ型というのは`int, boolean`などのことです。ただの値を示しているやつですね。著者はこれを使うことに固執するよりも、その値が表すクラスを作成し、構造体としてデータを表すことを勧めています。
10. スイッチ文
switch文は重複したコードを生み出す問題児です。switch文を見たら、ポリモーフィズムを使ってswitch文を置き換えられないか考えるべきです。ただし、今後も条件が追加されることがないような分岐に対してはこの限りではないです。
11. パラレル継承
12. 怠け者クラス
拡張性を見越して作られたが、拡張要求が来なかったりしてそのクラス自体があまり大きな役割をしていない場合を指します。こういったクラスは葬り去りましょう。
13. 疑わしき一般化
14. 一時的属性
15. メッセージの連鎖
16. 仲介人
オブジェクト指向の特徴として、カプセル化という概念があります。カプセル化はしばしば権限の委譲をもたらします。権限の委譲をしているオブジェクトを仲介人といいいます。仲介人としての仕事しかしていないオブジェクトは取り除くことを検討します。
17. 不適切な関係
18. クラスのインターフェース不一致
19. 未熟なクラスライブラリ
20. データクラス
属性とget/setメソッドしかないクラス。これらのクラスは他のクラスからのアクセスを過剰に受けがちになる。
21. 相続拒否
親クラスのフィールドやメソッドの一部しか使用されていないパターン。しかし、大きな問題になることは稀なので、不吉な臭いとしては軽い方。
22. コメント
コメントは不吉な臭いではなく、いい香りです。しかし、コメントがないと理解できないコードというのは、不吉な臭いを発する前兆と考えることもできます。そのため、コメントの代わりにメソッドの抽出、メソッド名の変更を行うことで、コメントが不要になることがあります。
コメントをする内容としては、以下が後々役に立つコメントの内容です。
- 不明点のメモ
- なぜその処理をしたのか