Combine Functions Into Class

関数群のクラスへの集約 動機 共通のデータに対して互いに関わりの深い処理を行う一群の関数があれば、クラスを定義するチャンスと考える。(共通データは通常は関数呼び出しの際に引数として渡さる。)クラスを使うことで、これらの関数が共有する環境がより明示的になり、関数の引数が大幅に減ることで、オブジェクト内の関数呼び出しを単純化できます。そうしたオブジェクトをシステムの他の部分に参照として渡すのも容易になる。 このリファクタリングは既存の関数群を体系化するだけではなく、他で断片的に計算を行っている箇所を特定し、新たなクラスのメソッドとしてリファクタリングする良い機会も与えてくれる。 手順 関数間で共有しているデータのレコードに「レコードのカプセル化」を施す。 関数間で共有しているデータが、レコード構造としてまとめられていない場合は、「パラメータオブジェクトの導入」を施し、それらをまとめるレコードを作る。 「関数の移動」を適用して、共通のレコードを扱う関数をそれぞれ、新たなクラスへと移す。 関数呼び出しの引数のうち、クラスのメンバになっているものは、引数のリストから取り除くことができる。 データを操作するロジックの断片があればそれぞれ、「関数の抽出」で抽出してクラスに移す。

February 20, 2022

Introduce Parameter Object

パラメータオブジェクトの導入 動機 データ構造体にまとめることには意味があり、データ項目間の関係を明示するとができる。 新たな構造体を使えば、関数のパラメータ数は少なくて済みます。その構造体を使うすべての関数が、構造体の要素を取得するのに同じ名前を使うことで、一貫性の向上にも役立ちます。 このリファクタリングの真価は、コードにより深い変化を引き起こすことにあります。新たな構造体を特定したら、その構造体を使うようにプログラムの振る舞いを改めます。一連の共通関数群になることも、データ構造とそれらの関数を組み合わせたクラスになることもあります。この過程でコードの概念的な構図が変化することもある。そうした構造体を新たな抽象に引き上げると、問題領域の理解がすっきりする。 手順 ふさわしい構造体がまだ存在しないなら、作成する。 後で振る舞いをまとめやすいのでクラスにすることが多い、構造体が「値オブジェクト」なのか確認するとよい。 テスト 関数宣言の変更を施し、新たな構造体用のパラメータを追加する テスト 新たな構造体の正しいインスタンスを渡すように各呼び出し側を修正する。1つの呼び出しを修正するごとにテストする 元のパラメータを使用している箇所を、新たな構造体の要素を使うように1つひとつ置き換える。元のパラメータを削除し、テストする。

February 20, 2022

Rename Variable

変数名の変更 動機 変数はうまく名前を付けさえすれば、目的説明する上で非常に役立ちます。しかし注意深く考えていない場合やユーザーのニーズが変わってプログラムの目的が変わったから、などがあり不適切な名前となることがある。 手順 変数が広く使われている場合、「変数のカプセル化」を検討する。 変数への参照をくまなく探し、それらをすべて変更数。 変数が別のコードベースから参照されている場合、その変数は公開されているので、このリファクタリングを行うことはできない。 変数が変更されない場合、変数を新たな名前の変数にコピーしてから、徐々に置き換えていき、その都度テストする テスト

February 20, 2022

Encapsulate Variable

変数のカプセル化 動機 スコープが大きくなるにつれて変更が困難になっていく。そのため広い範囲でデータを移動したいといは、カプセル化して、変数へのアクセスを関数経由にするのが非常に良いやり方。これでデータの再構成という困難な作業を、関数の再構成というより簡単な作業に変えることができる。 それ以外にデータの変更や参照を監視できるという明確な利点を得られる。データ更新の際の検証や後処理を追加するのも簡単。 スコープが1つの関数より大きいものは、関数を通じてのみアクセスできるようにし、データのスコープが大きくなるほどカプセル化はより重要になる。 手順 変数を参照・更新するためのカプセル化用関数を作る。 静的チェックを実行する。 変数への参照を、1つひとつ適切なカプセル化関数の呼び出しに置き換える。置き換えるごとにテストする。 変数の可視性を制限する。 変数への直接アクセスを防げないことがよくある。その場合、変数名を変更してテストすることで、置き換えが漏れた参照を見つけることができる。 テスト 変数の値がレコードの場合、「レコードのカプセル化」を検討する。

February 20, 2022

Change Function Declaration

関数宣言の変更 動機 関数宣言はソフトウェアシステムにおける継ぎ目となる。多くの部分が継ぎ目に依存し、良い継ぎ目があればシステムに新たな部品を追加するのは簡単。悪い継ぎ目は常に問題の発生源になる。 継ぎ目の要素で最も重要なのは関数名です。もし間違った名前の関数を見たら、少しでも名前がわかり次第、断固として変更していかなければなりません。 関数の名前を改善していくための良い方法は、関数の目的をコメントとして書くこと。そのコメントを名前に変更する。 手順 変更内容を吟味して、宣言と呼び出しとを一度で簡単に変更できるかを検討する。もしできるなら簡易な手順を実行する。 そうでなければ移行手順を選択して呼び出し側より漸進的に変更していく。 この手順が大きな意味を持つのは、呼び出し箇所が多い場合や(公開されたAPIのように)呼び出し箇所が手の届かないところにある場合、関数がポリモーフィックなメソッドである場合、関数宣言に複雑な変更を加える場合です。 簡易な手順 パラメータを削除する場合、それが関数内部で参照されていないことを確認する。 関数宣言を望ましいものに変更する。 古い関数宣言へのすべての参照を探し、新しいものに変更する。 テスト 名前の変更とパラメータの追加の両方がある場合には、それぞれ別のステップで実施する。 移行手順 必要なら関数の本体をリファクタリングして、移行の抽出のステップを実施しやすくしておく。 関数本体に関数の抽出を施して、新たな関数を作る。 新たな関数の名前を古いものと同じにする予定なら、新たな関数に判別しやすい名前を一時的に付けておく。 抽出した関数が追加のパラメータを必要とする場合、簡易な手順により追加を行う。 古い関数に「関数のインライン化」を施す。 一時的な名前を使った場合、「関数宣言の変更」を再び実施し、元の名前に戻す。 テスト

February 20, 2022