関数の移動

動機

関数を移動する最も直観的な理由は、その関数が存在するコンテキストの要素よりも他のコンテキストの要素を多く参照しえちる場合。移動によって、関数をそれらの要素と一緒にすると、カプセル化が改善することがよくある。別の関数内で定義されたヘルパー関数が単体で有用な場合は、よりアクセスしやすい場所に移動すると有意義。 関数の移動の判断はたいてい困難を伴います。その判断を下すには、その関数の現在のコンテキストを移動先候補のコンテキストを調べます。どの関数が移動したい関数を呼び出すか、移動したい関数がどのデータを使っているかを調べる必要がある。
関数のグループのために新しいコンテキストが必要になるケースは多いため、「関数群のクラスへの集約」や「クラスの抽出」によって新しいコンテキストを作成する。関数をどこに配置するのが最適かを決めるのは難しいかもしれませんが、通常はその選択が難しければ難しいほど、配置先を決める重要性は下がる。関数をあるコンテキストに実際に移動してみて、どれだけうまく適合するかを調べることは有意義。うまく適合しなかったしても、後からいつでも移動できる。

手順

  • 移動対象の関数が現在のコンテキストで使用しているプログラム要素をすべて調べる。それらも移動すべきかどうかを検討する。 呼び出している関数にも移動すべきものがあった場合、通常、まずはその関数から移動する。こうすることで、一連の関数の移動を依存性の低い関数から抽出できる。
    上位レベルの関数がサブ関数群の唯一の呼び出し元だった場合、それらのサブ関数群を上位の関数にインライン化し、移動した後で再抽出してもよい。
  • 選択した関数がポリモーフィックなメソッドかどうかを確認する。 オブジェクト指向言語の場合、スーパークラスとサブクラスに注意する必要がある。
  • 関数を移動先のコンテキストにコピーする。新居となる移動先に関数が適合するように調整する。 コード本体が元のコンテキスト内の要素を使用する場合、それらの要素をパラメータとして渡すか、あるいは元のコンテキストへの参照を渡す必要がある。
    関数を移動すると、新しいコンテキストにうまく適合する別の名前を付けたくなることがよくある。
  • 静的解析を実行する。
  • 元のコンテキストから移動後の関数を参照できるようにする。
  • テスト
  • 元の関数に対して「関数のインライン化」の適用を検討する。 元の関数は委譲関係として残しても良い。しかし、移動した関数を呼び出し元が簡単に呼び出せるなら、余分な仲介者は取り除くほうが良い。