リファクタリング 第1章
問題
- 構造的に機能を付け加えにくいプログラムに新規機能を追加しなければならない場合、どうすればよいか。
- リファクタリングをする時に、最初にすることは何か。
- メソッドを抽出した際に、抽出したコードの責務が元のクラスにないことがわかった。メソッドの移動をさせたいが、はじめに抽出したメソッドを消す前に、どのような過程を挟むのが安全か。
- メソッドの中だけで有効なローカル変数、一時変数は少ない方が良い。それはなぜか。
- 4の解決策は何か。
- リファクタリングによってメソッドの持つ責務を別々のメソッドに切り分けたことで、外部にどのような利点が生じうるか。
- 他のオブジェクトの属性を調べるswitchやif文を書くことは常に間違いであるが、それはなぜか。
- switch, ifによるオブジェクトの属性の分類は、同じ質問に対してオブジェクトが異なる処理をすることである。これはサブクラスの処理と考えられ、継承が利用可能である。しかし、オブジェクトの属性が度々変わる場合、それに合わせて派生先のサブクラスを変更することは出来ない。どうすればよいか。
解答・考察
- 先に機能追加が簡単になるようにリファクタリングをしてから新規機能を追加する。
- 一連のテスト群を作成する。テスト群は間違っている箇所を診断できるようなものにしておく。
- はじめに抽出したメソッドに、メソッドの移動先のクラスに委譲するコードを書く。(P.16, 17)
- 追うべき状態の数が増えるので複雑になる。状態が増える分、メソッドの責務が膨れ上がることに繋がりやすい。
- 問い合わせによる一時変数の置き換え。
- 切り分けたメソッドをインターフェースとして公開することが出来る。
- まず、switchやif文に想定れる変更は分類の追加である。分類の追加による影響範囲を小さくしたいので、switchやif文の対象となるオブジェクトに委譲すべきである。
- State/Strategyパターンによるタイプコードの置き換えを行う。
感想
[8]でState/Strategyパターンによるタイプコードの置き換えということを学んだ。Priceのポインタを持たせて動的多態作るということだと思うが、C++で、CRTP, tag dispatch, SNIFAEなど使ってうまいこと静的に実現出来ないのだろうか。属性がコロコロ切り替わるから厳しい?