このページをはてなブックマークに追加このページを含むはてなブックマーク このページをlivedoor クリップに追加このページを含むlivedoor クリップ

目次

リファクタリング(refactoring)

  • 外部から見たプログラムの振る舞いを変えずに、プログラム内部の構造を改善すること。
    • プログラムの正しい動き、即ち外側から見た機能を変えずに、中身を整理してわかりやすくすること。
  • 1980年代にSmalltalkのコミュニティから生まれ、マーチン・ファウラーの『リファクタリング プログラミングの体質改善テクニック』やケント・ベックの提唱するアジャイル開発手法であるXPのプラクティクスのひとつとして有名になった。
  • 正しい手順を踏まないリファクタリングはリスクが高い。
    • リファクタリングを行う前に単体テストを行ってからリファクタリングを行う。その後、また単体テストを行う。
      • 繰り返し単体テストを行うため、テストクラスを用意すべきである。
  • リファクタリングをすると一般に「オブジェクト指向で書かれ理解しやすいプログラムができあがる」と考えられているがこれは誤解である。
    • リファクタリングはパフォーマンスの観点からあえてオブジェクト指向のような理解しやすいプログラムから、オブジェクト指向のようでない理解しにくいプログラムに変えることもある。つまり、リファクタリングには裏表があるわけである。どちらが適した実装であるかどうかは状況に依存する。パフォーマンスを重要視するか、読みやすさを重要視するかなどである。
  • 経験の浅いプログラマは「後でリファクタリングするから」といい、汚くても動けばよいと考えてコードを書いてしまう人も少なくない。しかし、それはリファクタリングで修正すべき「におい」に対する嗅覚が発達していないということである。嗅覚が発達している熟練者の場合は、新規にコードを一人で書いているときでさえ、「におい」を感じたら、その場でコードを修正し始める。もし「後でリファクタリングするから」と言い訳して、明らかにリファクタリングしなければならないような悪臭を放つコードを書いているエンジニアがいたら要注意である。
  • バグ取り、機能追加はプログラムの振る舞いが変わるため、リファクタリングではない。

リファクタリングを行うタイミング

  • 3度目の法則
    • 最初は普通にコーディングする。次に他のコーディングをしているときに似たロジックを書いた気がすると思っても放っておく。さらに新たに3度目の気付きがあったときに行う。
  • 機能追加をする前
    • 機能追加をする前にリファクタリングをしておくことで、コードの復習になり機能追加しやすくなる。
    • 特に初心者の場合は機能追加とリファクタリングを同時にやらないこと。
  • バグフィックスの作業後
    • バグが発生したプログラムの理解のために作業をする。
  • レビューのときまたは直後
    • レビューでリファクタリングすべき箇所について指摘されることもある。
  • 1つの機能を作成し終えたとき
  • 作業が中断してしまったとき
    • 顧客が現在の作業を進めてよいかどうか判断に迷うなどして、開発プロジェクトの作業が途中で中断することがある。このときは、次の要求変更を受け入れやすくするためにも、リファクタリングしておく。

DB操作のリファクタリング

  • Connectionのclose()処理はfinallyで行う.
  • commit(),rollback()は複数のINSERT処理がある場合に使用する。
    • SELECT文のようにDBに影響を与えない操作の場合や、1回のUPDATE,INSERT,DERETE操作の場合は不要である。
  • ResultSet*1にはclose()メソッドがあるが、Statementがcloseされるときや再実行されるとき、一連の複数結果から次の結果を検索するために使用されるときは自動的にResultSetはcloseされる。
  • Statementを使用しているとシングルクォート(文字列の場合はシングルクォートで挟み、数値の場合はシングルクォートで挟む必要がない)の問題が出てくる。これを回避するためにStatementの代わりに、PreparedStatementを使えばよい。
    • そうすれば、SQLインジェクションなどに対しても安全性が増す。
  • DAOクラスにはトランザクションの開始と終了は含めるべきではない。
    • なぜならば他のDAOクラスと組み合わせて1つのトランザクションにすることができないからである。つまり、DAOクラス側にトランザクションの開始・終了があるのではなく、Manager側でトランザクションの開始・終了しなければならない。

パッケージのリファクタリング

  • 開発前にパッケージをうまく設計できていたとしても、実装中に機能追加や要求変更などでクラスが追加されたりクラス間の関係が変わることにより、パッケージ間の依存関係が増えたり、パッケージ間の結合度が高くなってしまうことがあう。
    • そのようなパッケージは管理・保守・再利用の観点からリファクタリングをする必要がある。
  • Eclipseのリファクタリング機能を利用すれば、パッケージ名を変更して用意にパッケージのリファクタリングができる。
    • ただし、パッケージ名が記述されているXML形式などの定義ファイルまでは自動的に修正されないので、こうしたものは手作業での修正が必要である。
  • クラスのimport文に「*」を利用しているとクラス間の関係がわかりづらいので、「*」を止めてクラス名を書くようにする。

参考文献

  • 『バグがないプログラムのつくり方 JavaとEclipseで学ぶTDDテスト駆動開発』
  • 『プログラムの育てかた』
  • 『ソフトウェア開発の名著を読む』
  • 『Java言語で学ぶリファクタリング入門』


*1 SELECT文の実行結果を得る場合に使用する。