未知のバグを修正することはリファクタリングでしょうか
2004年9月3日
プシェミスワフ・ポクリブカが出した興味深い難問をご紹介します。著書のリファクタリングの1つにヌルオブジェクトの導入があります。これは非常に便利なリファクタリングであり(ジョシュの新著でも説明されています)。プシェミスワフは、このリファクタリングは動作を変更する可能性があると指摘しています。メソッドからヌルが返されて、ヌルに対してメソッドを呼び出すと、ヌルポインター例外が発生します。ヌルオブジェクトを使用すると、何らかの既定の動作が発生します。
実際、動作を変更するリファクタリングは多く、実際それが目的です。テンプレートメソッドの形成を適用すると、プログラムの動作が変わります。重要なのは、これが私のDefinitionOfRefactoringでいう観測可能な動作かどうかという点です。つまり、プログラムの本質的な動作が変わるのでしょうか?ヌルオブジェクトの導入では、プログラム内の参照を操作する場所(通常ヌルかどうかを確認)を注意深く確認する必要があります。これにより、リファクタリングは非常にやりにくくなります。
この難問の興味深い点は、バグが存在する領域を見逃した場合にどうなるかという点です。プログラムのどこかで、ヌル参照に対するメソッドを呼び出します。リファクタリングの前は例外が発生します。ここでは、不明でトップレベルのハンドラにまで達してしまうような例外が発生すると想定します。リファクタリングの後は、バグを修正できる場合がある既定の動作が発生します。不明なバグを修正するのはリファクタリングではないでしょうか?
私はリファクタリングだと主張します。バグのある動作を知らなかったり、気にしなかったからです。その動作は観測できなかったということでしょう。バグがわかっていたとしても、そのバグを維持する必要がないと判断すれば、リファクタリングと呼んでもかまわないと思います。
これは興味深いケースであり、自分自身でも考えを変えたり、他の難問を検討したりすることは想像に難くありません。
興味深い点の1つは、手動リファクタリングとツール駆動のリファクタリングの違いです。手動リファクタリングでは、ツールでは十分に注意する必要があることが多く、このような判断を下すことができます。しかし、ツールが動作を確実に維持できるとは限りません。リネームメソッドでさえ、リフレクションでメソッドがファイルから読み取る名前で呼び出された場合、リファクタリングで壊れる可能性があります。