$shibayu36->blog;

クラスター株式会社のソフトウェアエンジニアです。エンジニアリングや読書などについて書いています。

レガシーコード改善ガイドを読んだ

レガシーコード改善ガイドを読んだ。

この本では、レガシーコードの内部をリファクタリングする際に何を気にする必要があるかとか、非常に長いモンスターメソッドをリファクタリングしていく時にまずどこからやるかとか、そういうことが書いてある。とにかくレガシーコードに直面して何から始めたらいいかわからないという時にはおすすめ。

リファクタリングという本と近い内容だけど、僕の中ではこの本よりはリファクタリングの方がなんとなく肌にあった。また今度再読してみようと思う。

印象に残ったところを書いていく。

依存関係を排除する

 「たいていの場合、テストの最大の障害となるのが依存関係です」と書いてあるのだけれど、これは確かにと思った。いつもは無意識にやっているけど、言語化されてよかった。

 例えばあるクラスのメソッドに対してテストを書きたい時、よく困るのは依存しているクラスが外部と通信していてテストが書けない、みたいなことがある。この時、どうやって依存関係を排除するのかが重要。

 やり方はいろいろあって

  • そもそもシンボルが指し示すクラスをリンク時にダミークラスに差し替えてしまう(リンク接合部での処理)
  • 引数で渡せる時は、ダミーオブジェクトを渡すとか
  • オブジェクト自体の一部メソッドだけ書き換える
  • etc

などがある。この本ではJavaC++の言語を使っているので、渡す時は具象クラスに依存せずに、インターフェースに依存させることで、テスト用のダミーオブジェクトに差し替えることが可能になり、依存を排除できるみたいなこととか書いてあった。PerlRubyなどの動的言語を利用していると、あるメソッドが呼んでいるメソッドをテスト内だけ再定義して、依存を排除するというやり方が主だと思う。

 いろいろと書いてあるけど、あるクラスをテストするときに他のクラスの条件や処理のことを考えずに書けたほうがテストは書きやすい。そのために依存関係がどのようになっているか考えながらテストかけると良さそうと思った。

テスト駆動開発の手順

 98ページくらいからテスト駆動開発の一例が書かれているのだけど、これが非常に参考になる。

  1. 失敗するテストケースを記述する
  2. コンパイルする
  3. テストを通過させる
  4. 重複を取り除く
  5. 繰り返す

 何が良いと思ったのかというと、一度にいろいろなリファクタリングをせずに、1つずつやっていって繰り返すという例になっているのが良い。

 リファクタリングをしようと思った時、最初から綺麗にしようとしすぎて、いろいろ触ったら、確認漏れがあってバグを作ってしまったということをよくやってしまう。そうでなくて、まずリファクタリングしようと思ったところにテストを書いて保護した後、その部分に関するリファクタリングのみを行って確認するという風に書いてある。リファクタリングは振る舞いを変えるわけではないので、いくらでも作業単位を小さくできるので、このように繰り返す手法のほうがバグも発生しにくいと思う。

試行リファクタリング

 226ページくらいから書かれている試行リファクタリングという章も興味深い。

 このコードが良くわからないと思ったら、まずは試しにリファクタリングしてみると学習が深まるということが書かれている。その時、コードを最終的に保存する必要はなくて、学習のためにあれこれリファクタリングしてみて、最後に破棄することでその部分に対して知識が深まると書いてある。なんとなく今度試してみたいと思った。

まとめ

 自分の中では少し肌に合わない部分もあったのだけど、参考になる部分も多い本だった。

 これを読んでもう一回リファクタリングやコードコンプリートを読まないとなーという気分になってきたので、この二つを再読したい。