リファクタリング: Rubyエディション 第2章

## はじめに

<img src='https://qiita-image-store.s3.amazonaws.com/0/186009/5d219e32-cd26-4cbd-1390-ad61e884ade0.jpeg' height=300px >

Amazon: https://www.amazon.co.jp/dp/4048678841

今回は `リファクタリング: Rubyエディション` の `第2章 リファクタリングの原則` をまとめました。

## リファクタリングとは？

この本では、リファクタリングについて以下のように書かれています。

> まず第1に、リファクタリングの目的は、ソフトウェアをわかりやすく直しやすいものにすることだということである。

引用元: `リファクタリング: Rubyエディション` P77 L18~19


> ソフトウェアには外から見たふるまいにほとんど、あるいはまったく変化を与えないような変更をいくらでも加えることができるが、ソフトウェアをわかりやすくする変更だけをリファクタリングと呼ぶ。

引用元: `リファクタリング: Rubyエディション` P77 L19~21


> 強調しておきたい第2の点は、リファクタリングでは、ソフトウェアの外から見たふるまいが変わらないことだ。

引用元: `リファクタリング: Rubyエディション` P77 L26~L27

つまり「ソフトウェアの外から見たふるまいを変えずに、 **人間にとって** わかりやすく、直しやすいものにすること」だというように受け取りました。

## なぜリファクタリングをするの？

ではなぜ人間にとってわかりやすく、直しやすいようリファクタリングするべきなのでしょうか？

この本では、大きく分けて3つの観点で理由が書かれています。

### 設計を改善するため

チームで開発していると、様々な人がコードに変更を加えることになります。コードの設計を理解しないまま変更されたり、 `dirty hack` であるのはわかっているけれどリリース優先で仕方なく変更されたりすることもあります。

その結果、重複するコードがいたるところに散らばったり、わずかに異なる文脈でほぼ同じコードがかかれてしまったりと、設計がわかりにくくなってしまいます。

そうすると、いざ修正が行われるときに、変更しなければならないコードが増えるだけでなく、設計を理解するために読まなければならないコードの量も増えてしまいます。

だからこそ、重複するコードを削除したり、あるべきコードをあるべき場所に移動させたりして、コードの構造をわかりやすく保たなければならないということでした。


### ソフトウェアをわかりやすくするため

コンピュータを正確に動かすことだけに注力し、人間が意味を理解しづらいコードを書いてしまうと、修正時の時間的・精神的負担が大きくなってしまいます。これはチームの他のメンバーだけではなく、未来の自分自身への負担になりかねません。

だからこそ、人間にとって読みやすいコードを書くことは大事ですが、自分がよく知らないコードを見かけたら、わかりやすいようにリファクタリングをしながら書き換えていくことも推奨されています。

そうすれば、自然とコードの理解も深まるだけでなく、そのコードや設計について覚えなくても読めばわかるようになるという利点もあります。


### バグを見つけやすくするため

定期的にリファクタリングをかけてコードがわかりやすくなれば、コードへの理解も深くなります。

理解が深くなれば、必然的にバグも見つけやすくなり、不具合修正にかかる時間も少なくなるはずです。

だからこそ、定期的にリファクタリングをかけようということでした。


### つまりは開発スピードの向上に帰着する

結局のところ、今まで述べてきたことは、 **リファクタリングによって開発のスピードを上がる** ということに帰着します。

設計がまずければ修正に余計な時間がかかってしまうかもしれませんし、新しい機能を追加するためにではなく、バグを見つけて直すために時間を費やしてしまうようになってしまうかもしれません。

ソフトウェア開発のスピードを上げるために、リファクタリングを行なって、優れた設計、人間にとってわかりやすいコードの構造を保つべきだということです。



## いつリファクタリングをすればよいの？

リファクタリングをすべき理由はなんとなく理解できましたが、どういったタイミングでリファクタリングをするべきなのでしょうか。


### 機能を追加するとき

新しく機能を追加するときは、既存のコードを理解した上で実装することが多いと思います。既存のコードがわかりづらかった場合は、コードの理解を深めるためにも、まずはコードをわかりやすくリファクタリングすることを勧めています。

また、機能を簡単に追加できない設計と対面したときは、無理に追加するよりも、リファクタリングして追加した方が速いとのことです。さらに言えば将来の機能拡張も楽に実装できるようになります。

つまり、機能を追加する際には既存のコードを理解する必要があるので、リファクタリングの絶好のタイミングだということでした。


### バグフィックスが必要になったとき

先にも書きましたが、不具合が報告されるということは、バグに気づけないだけコードが不明瞭になってしまっていることを示しています。

よって、不具合報告が届き、バグフィックスが必要になったときは、リファクタリングが必要なタイミングだと言えます。


### コードレビューをするとき

チームで開発している限り、自分にとって読みやすいコードが他のメンバーにとってはそうではないということが起こりえます。

そういうときこそ、コードレビューで意見交換を行い、チーム全体で理解しやすいコードを書いていくことが必要になります。

よって、コードレビューをするときが、リファクタリングを行うタイミングになるとのことです。


### リファクタリングのタイミングは常にある

上記で挙げた3つのタイミングで共通しているのは、いつも行なっている作業だということです。

リファクタリングは **特別な時間を設けるのではなく、いつもの作業の一部として一気に推し進めるべき** だということでした。



## リファクタリングが開発スピードを上げる仕組み

上記から、 **開発スピードを上げるために、常にリファクタリングをしながら開発する体制を整える** ことが大切だというふうに私は受け取りました。

リファクタリングの体制が整うことで、なぜ開発スピードを上がるのか、そのメカニズムが書かれていたので、まとめてみました。

開発効率を上げようとしているときに、手戻りの発生は非常に大きな課題となるでしょう。その結果、手戻りが発生しないように設計を正しく行わなければならないというプレッシャーが強くなります。

すると、**どんな場合にでも対応できる柔軟な設計を目指し、コードがかえって複雑な構造** になってしまいがちです。 **複雑な構造はメンテナンス性を著しく下げる** ことに繋がります。

しかし、リファクタリングの体制が整っていれば、事前設計で完璧な解を探さなくてよくなります。

なぜなら、機能追加をするたびにリファクタリングをすることで、コードや設計への理解が深まることを知っているので、 **最良の解は最初に考えた解とは異なる** ということを普段から実感できているからです。

ですから、 **設計後の変更に対するコストもそこまで高く感じない** ということです。

また、最善の解が常に変わる可能性があるということを受け入れると、 **設計の単純さ** を求めるようになるようです。

なぜなら、単純な設計であればあるほど、様々な場合に対応しやすいからです。

つまり、リファクタリングは **柔軟さを犠牲にせずに設計の単純化に導き** 、その単純さのおかげで人間が理解しやすくなるため、開発スピードが上がるということでした。

## 関連

- [リファクタリング: Rubyエディション 第6章](https://qiita.com/tamago3keran/items/898936b716984cd55b1f)
- [リファクタリング: Rubyエディション 第7章](https://qiita.com/tamago3keran/items/d435f6c1280f8de29ad4)
- [リファクタリング: Rubyエディション 第8章](https://qiita.com/tamago3keran/items/2de394cfa1d36fdba924)
- [リファクタリング: Rubyエディション 第9章](https://qiita.com/tamago3keran/items/2818b20cdc42bb9c5388)
- [リファクタリング: Rubyエディション 第10章](https://qiita.com/tamago3keran/items/81a7fbd68d33c705b452)
- [リファクタリング: Rubyエディション 第11章](https://qiita.com/tamago3keran/items/aeee895399655b9c701b)