The King's Museum

ソフトウェアエンジニアのブログ。

リファクタリング【第2版】- 第1章:リファクタリング - 最初の例

マーティン・ファウラーの『リファクタリング』を読み始めました。

初版が出たのが 1999 年。いつか読みたいと思っていたけど、さすがに内容が古いのかなと思って読んでいなかった。 第2版が出たと聞いて調べてみたら、コード例が JavaScript になって今風になったということで読んでみることにした。

毎日ちょっとづつ読み進めていって章ごとに記事にまとめようと思う。 時間はかかるけど、この本にはそれだけの価値があるはず。

第1章: リファクタリング - 最初の例

第1章は JavaScript で書かれたコードを実際のリファクタリングによって改善していく様子が書かれている。 理論を説明するための前準備として「実例を出す」というのが著者のスタンスらしい。

請求書を発行する JavaScript の 100 行ほどのコードが例になっている。 ここではいくつかのリファクタリングのテクニックが用いられている。

  • 関数の抽出
  • 問い合わせによる一時変数の置きかえ
  • 関数宣言の変更
  • 変数のインライン化
  • ループの分離
  • ステートメントのスライド
  • フェーズの分離
  • 関数の移動
  • ポリモーフィズムによる条件分岐の置きかえ

それぞれの詳細な説明については第2章以降に書かれている。 これらのテクニック一つ一つはとても単純なもので自分もコードを書くときに使っているものもある。

でも、『問い合わせによる一時変数の置きかえ』と『変数のインライン化』はあまり使わないかもしれない。

これは、

for (let product of producst) {
  let thisAmount = getAmount(product);
  ...
  result += `${format(thisAmount/100)}`; 
  totalAmount += thisAmount;
}

というようなコードがあったときに、変数を用いずに次のようにすることだ。

for (let product of producst) {
  result += `${format(getAmount(product)/100)}`; 
  totalAmount += getAmount(product);
}

後者の方が、変数がすくなくて状態が一つ少ないという点、関数の抽出がやりやすくなるという点が有利である。

ただ、個人的には一時変数にいれておいたほうが値がラベリングされていて見やすいんじゃないかと思う。 この時、変数が可変(let)じゃなくて不変(const)になっていることが条件だけど。 関数呼び出しがあるとどうしても副作用を気にしてしまってコードを読むスピードが少し落ちる。自分の場合だけど。

関数呼び出しを二回することでパフォーマンスの方を気にする人がいるかもしれないが、個人的にはこのケースならパフォーマンスは気にしない。 この点は本でも言及されている。

ここで指摘したいのは、この変更はパフォーマンスに大きな影響を与えないし、たとえそうであっても、コードが整然としていれば後からチューニングが容易にできるということです。

--

自分は何かの修正があるとき、修正の内容を意識しながらまずはリファクタリングしてコードを整えてから修正を加えるようにしている。 この方が変更がシンプルになりやすいし、コードレビューしてもらう時に差分が分かりやすいからだ。

構造的に機能を加えにくいプログラムに新規機能を追加しなければならない場合には、まず機能追加が簡単になるようにリファクタリングをしてから追加すること。

このやり方だと作業時間は少し長くなりがちでデメリットもあるんだけど、この本と意見が同じで少し安心した。 まぁリファクタリングの本だし当然といえば当然か。

(c) The King's Museum