『新装版 リファクタリング』の感想

はいどーも人生をリファクタリングしたい無職です。
本日は『新装版 リファクタリング』の感想を書いていきたいと思いますよ。

副題の意味

本書の副題は「既存のコードを安全に改善する」です。
リファクタリングのことをよく知らなかった僕は副題の意味を「古臭い書き方で作られたコード(既存のコード)を、テストを使って安全に改善していくんだろぉ?」と勘違いしていました。
ですが読み進めるにつれて、「既存のコード」とは別に古い書き方で作られたコードのことだけではないことがわかってきました。
過去のある時点(主に最初に書かれた段階)では適切であったコードが、様々な人の手によって書き換えられていくうちに不適切なものになることがあるのです。
だからこそ、全く真逆のリファクタリングが成立するとも言えます。
例えば

・クラスの抽出
・クラスのインライン化

なんてのはもろに正反対のことです。

・委譲による継承の置き換え
・継承による委譲の置き換え

も全くの逆ですし、僕はどちらかと言えば今まで「委譲による継承の置き換えこそが正しい書き方だ」とさえ思っていました。
ですが、どちらも同じリファクタリングなのです。
とはいえ適切か不適切でないか(不吉な臭い)は経験に依るところが大きいのかな、とは思いましたが。

リファクタリングの意義

リファクタリングは単に「コードの見た目を綺麗にして、人がプログラムを読みやすくする」だけではありません。
リファクタリングをおこなうと、その改善しようとしている複雑怪奇なコードへの理解が進みます。
理解が進むと新たな不具合を発見できるかもしれません。
また、リファクタリングするとコードの構造が見通しやすくなり、結果として機能の追加が容易になります。
もしリファクタリングせずに機能追加しようとすれば2時間はかかったであろうところを、リファクタリングに1時間割いたおかげで、機能の追加自体は10分程度で済んだ、ということは僕も実際にありました。
もちろん「コードの見た目を綺麗にして、人がプログラムを読みやすくする」というところも大事ですが。

コメントの必要を感じたときはリファクタリングをおこなう

本書は「コメントを書かなくとも内容がわかるコード」を目指そう、と書かれています。
これには僕も大いに同意するのですが、やはり英語圏の人間ではないので(プログラムのコードって大抵の場合は英語ですから)、多少はコメントがあった方がわかりやすいかな、とは思います。
また、「なぜそのコードを書いたのか」は積極的にコメントに残すようにもしています。
例えばC#でLINQのSelectを使えば一行で書けそうなコードを、長々とfor文で書いていたとします。
もし何もコメントがなければ「なんだこのコードは。LINQを使って書き直そう」と思うかもしれません。
ですが実はその部分がfor文で書かれていたのにはきちんとした理由(例えばパフォーマンスの問題だとか、対象としている機種でLINQが動かなかったりだとか)があったとしたら、どうでしょう。
これはコメントを書いておかないとわかりません。そのfor文を書いた本人ですら、数ヶ月後には忘れているでしょう。
逆に不要なコメントとは、例えば一つのメソッドの中で以下のような処理をコメント付きでおこなっている場合ではないでしょうか。

//サーバーからコメントデータ郡を取得してくる
...処理内容
//取得したコメントデータ郡を加工し、プログラム内部で扱える形にする
...処理内容
//コメントデータ郡の中から、文字数の長い順に5つ抽出する
...処理内容
//抽出した文字列をつなぎ合わせ、デコレートする
...処理内容

これらは一つのメソッドとするよりも、それぞれ別のメソッドとして抽出してあげるのがよいんじゃないかなーと思います。
そうすれば、一つ一つのメソッドに適切な名前をつけることも簡単でしょう。

テストの必要性

リファクタリングとテストはやはり一セットのようで、本書でも何度も「テストは書こう」と言われています。
また、テストを書くことをためらう読者(僕みたいなのw)のために「実行されない完全なテストよりも、実行される不完全なテストのほうがましである」とも書いています。
つまり「少しでもいいからテストを書こう。完全なテストを最初から書く必要はない。書かないよりは書いたほうがマシなのだから」というスタンスなのですね。
ツクールMVだと残念ながらテストが書きにくすぎて(みなさんどういう開発環境を用意してるんでしょうね?)assertを使うくらいでテストを作ったことはないのですが、C#での開発では積極的にテストを用意しようと思いますよ。

リファクタリングカタログ

本書のコードは全てJavaで書かれています。
最も力を入れて書かれたと思われる「リファクタリングカタログ」もJavaです。
ですがこのリファクタリングカタログはオブジェクト指向言語を利用しているなら、ほとんどの場面で役立つのではないかなと思います。
というか、オブジェクト指向言語でなくても役立つんじゃないでしょーか。
数が多いので一気に全てを完璧に把握することはさすがに無理ですが、「リファクタリングしないよりは少しでもリファクタリングした方がマシ」と思って、ちまちまやっていこうと思いますよ。

個人的な発見

リファクタリング技法の一つに「問い合わせと更新の分離」というものがあります。
例えば値を返す関数があったとします。この関数に副作用がなければ、この関数はいつでもどこでも呼び出して大丈夫です。
逆に副作用を持つ関数は、いつでもどこでも呼び出してしまうと、問題が起こるでしょう。
「単に関数の戻り値を受け取りたいだけなのに、副作用があるせいで呼び出せない」ということが発生するであろうことは容易に想像できます。
そこで本書では「値を返すメソッドはすべて、観測可能な副作用を持たないと決めて」しまおうと説いています。
僕も最近はこれを意識しています(なお「観測可能な」というところもミソです)。
単純なことですが、これを意識するだけでもコードの複雑度がグンと下がるんじゃないかなと感じていますよ。
関数型言語で副作用を持たすことはダメ! みたいな話もこれと同じなのかな? と思いました(関数型はまだほぼ勉強したことがないので間違ってるかもですが)。

終わりに

リファクタリングの本を読んだのはこれで二冊目です。
あと一冊『レガシーコード改善ガイド』を読んでみたいのですが、他にも色々と読みたい本があって、ウムムム……という感じです。
本書については、自分がどれくらい成長したのかをするために一年後くらいにまた読んでみたいですね。

ほなそんな感じでまた。

フォローする