私が思うリファクタリングとリストラクチャリングの違い
id:makotanさんからmixiの日記でコメントをいただいて
思ったことをはてなに書いてみる。
最近リファクタリングは設計を進化させるだとかをよく聞くが
私はリファクタリングはソフトウェアの体質改善であり
publicなメソッドのインタフェースを変えてしまうような修正を
リファクタリングだとは呼びたくないです。
なぜなら一般的なソフトウェアテストの単位はユニット単位だし
リファクタリングを行う前提としてユニットテストを
書いておくことが必須だと思うからです。
例示をしてみる。
先日、現場で以下のようなメソッドのSRP違反のコードを見つけた。
Beanの生成および設定とHTMLの作成を行っているようだ。
public void createHTML(String fileName) {Bean bean = new Bean();
// Beanに対する設定// HTMLの作成
VelocityContext context = new VelocityContext();
context.put("bean-name", bean);
BufferedWriter writer = new BufferedWriter(new FileWriter(fileName));Template template = Velocity.getTemplate(vmName);
template.merge(ctx, writer);writer.flush();
}
メソッドの複数の責務を改善し単一の責務とするには
Beanを戻り値にしてHTMLの生成を別メソッドに修正することである。
しかしここで気になったのはこのメソッドはpublicなメソッドだということだ。
publicメソッドは外部のクラスからも呼び出しが可能なため
メソッドの複数の責務を改善することによって
呼び出し元のコードにも影響が出るということになる。
私はこういう外部に影響が出てしまう改善は
リストラクチャリングになるのではないかと思った。
テストケースを複数に分割する必要性があり
追記:これはリファクタリングの話と別なので削除。
他のクラスに影響を及ぼす可能性がある修正を
リファクタリングだと思わなかったからです。
Martin Fowlerの日記にもあるが
私もシステムが動かなくなる可能性がある修正はリファクタリングだとは思いません。
リファクタリング中に2,3日システムが動かなくなっちゃってーなどと言ってる奴がいたら、んなもんリファクタリングじゃあなーいと言ってやれ。
よってこういう変更は設計上良いプラクティスだとは思いますが
リファクタリングだと呼ぶのはいかがなものか?*1
私が出した例のごとく勝手な推測と結論は以下です。
・ソフトウェアの単体テストの単位がユニットだとするとユニットテストの範囲を超える部分にまで影響を及ぼす可能性がある修正はリファクタリングではなくリストラクチャリングではないか?
・リファクタリングはソフトウェアの設計を進化させるとよく言われるが、上記を考えるとあくまで内部構造の改善に使われるべきである。
です。
追記:私はMartin Fowlerがとても好きですし尊敬しています。
*1:著者にたてつくとはなんて奴だ(w