リファクタリングについて

# 「リファクタリング」の記事を書こうと思った動機について
本記事を書こうと思ったのは、熟練エンジニアの方との話がキッカケでした。
ある案件のリリース直後、SEとして活躍されていた熟練のエンジニアの方と
新規機能の実装について話をしていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255982/405842a6-715e-d728-d773-fd2e226b5e40.png)
私はその新規機能の実装を担当しており、不具合なくリリースまで持っていけたのですが
コードが冗長だったためリファクタリングをしたいと強く思っていました。
リファクタリングをしたいという思いをその熟練のエンジニアの方に伝えたところ、
その方は渋い顔をして「テストの工数がね。。。」と話を流されてしまいました。
その時思ったのが、リファクタリングを推進するならリファクタリングによって得られる
メリット・デメリットを説明できないといけないと思い、勉強しようと思いました。

#本投稿のアジェンダ
本投稿のアジェンダは、以下の通り。

- リファクタリングの定義
- リファクタリングする際に必要なもの
- リファクタリングのメリット・デメリット
- ソフトウェア開発プロセスとの関連性

#参考書籍
本投稿をまとめる上で参考にした書籍は、以下の通り。
[リファクタリング 既存のコードを安全に改善する（第2版）](https://www.amazon.co.jp/%E3%83%AA%E3%83%95%E3%82%A1%E3%82%AF%E3%82%BF%E3%83%AA%E3%83%B3%E3%82%B0-%E6%97%A2%E5%AD%98%E3%81%AE%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E5%AE%89%E5%85%A8%E3%81%AB%E6%94%B9%E5%96%84%E3%81%99%E3%82%8B%EF%BC%88%E7%AC%AC2%E7%89%88%EF%BC%89-%EF%BC%AD%EF%BD%81%EF%BD%92%EF%BD%94%EF%BD%89%EF%BD%8E%EF%BC%A6%EF%BD%8F%EF%BD%97%EF%BD%8C%EF%BD%85%EF%BD%92-ebook/dp/B0827R4BDW/ref=bmx_2/355-6016739-1489235?_encoding=UTF8&pd_rd_i=B0827R4BDW&pd_rd_r=b2f45c72-6185-4932-b4c4-899105af9e46&pd_rd_w=1bYFf&pd_rd_wg=u52vK&pf_rd_p=8b1b8ea6-92a9-4574-b298-fca3f890acd3&pf_rd_r=DXRRFVX67P0HSW7QB63A&psc=1&refRID=DXRRFVX67P0HSW7QB63A)

# リファクタリングの定義
「リファクタリング」は、名詞と動詞として使われている。
説明は、以下の通り。(参考書籍から説明を抜粋。)

**リファクタリング(名詞)**
> 外部から見た時の振る舞いを保ちつつ、ソースコードの理解や修正が簡単になるように
> ソフトウェアの内部構造を変化させること。

**リファクタリング(動詞)**
> 一連のリファクタリングを適用して、外部から見た振る舞いの変更なしに、
> ソフトウェアを再構築すること。

コードを綺麗にする作業を「リファクタリング」と漠然と言ってしまいがちですが、
実際のところはコードを綺麗にするための特定の手法を「リファクタリング」と言う。

「リファクタリング」の定義を「外部から見た振る舞い〜」とあえて抽象的にしている。
その理由は、「リファクタリング」を実施したことによって処理順序や処理速度、IFが
変わる可能性があるからである。しかし、変更が加わったとしてもユーザ側が意識することはない。
「リファクタリング」を実施したソースコードは、実施前後と比較した際に
総じて同じ動きをすべきであると述べている。

# リファクタリングする際に必要なもの
「リファクタリング」を実施する上で必要なものと手順は、以下の通り。
### 「リファクタリング」をする際に必要なもの
- バージョン管理ツール
- テストコード、テストスイート

### 「リファクタリング」の手順
1. リファクタリングの対象となる箇所を実装する。
2. 修正箇所のテストを実施する。
3. 修正対象成果物をコミットする。
4. 1〜3の手順を繰り返す。

※もし、テスト実施時にバグが混入した場合は修正前の状態に戻す。

「リファクタリング」は、コンパイル→テスト→コミットのサイクルを繰り返す(下図参照)。
この時にポイントとなってくるのは、少ないステップ数で修正を繰り返すことである。
少ないステップ数で修正することでテスト実施時にバグの早期発見に繋がるからである。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255982/d2fcbc7c-432e-52f8-8896-0308494d9501.png)

# リファクタリングのメリット・デメリット
リファクタリングのメリットは、以下の通り。
### リファクタリングのメリット
- ソフトウェア設計の改善を図れる。
- ソフトウェアを理解しやすくなる。
- バグの発見に繋がる。
- 開発スピードが向上する。

##ソフトウェア設計の改善を図れる。
リファクタリング無しだとプログラムの内部の設計(アーキテクチャ)は、徐々に劣化していく。
また、アーキテクチャの理解なしに変更を加えてしまうとコードの構造が壊れてしまう。
このような状況に陥ったら設計の品質を維持するのが難しくなるため、劣化が進んでしまう。
上記の状況を回避できるのが「リファクタリング」である。
定期的に「リファクタリング」を行うことで、コードを良い状態に保つことができる。
コード上に「重複箇所」があるのは、設計としてまずい状態にある。けれども定期的に
「リファクタリング」を実施していれば「重複箇所」を無くせるため優れた設計になる。

##ソフトウェアを理解しやすくなる。
ソフトウェアを改修する上で将来のことを見据えて手を加えることが大切である。
他者から見て理解しやすいソースコードに修正することで現行の処理の流れを
理解する時間が短縮できる。
他者が理解しやすいソースコードに修正できるのが「リファクタリング」である。
※ここで述べている「他者」は、数ヶ月後の自分も含む。

##バグの発見に繋がる。
「リファクタリング」をしたことによって、理解しやすいソースコードに変わると
既存のバグを見つけやすくなる。

##開発スピードが向上する。
「リファクタリング」によって、最終的には開発のスピードが上がります。
「リファクタリング」によって内部の設計が改善される。その状態で新たな機能を
追加しようとしても変更を加える箇所が明確であるため開発のスピードが上がります。
「リファクタリング」の目的は、少ない労力で多くの価値を生み出し実装の速度をあげることにある。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255982/f6ce0989-9cc2-9b15-439f-b035df843ed6.png)

リファクタリングのデメリットは、以下の通り。
### リファクタリングのデメリット
- 進捗度と品質のバランスを保つのが困難。
- バージョン管理が複雑になる。

##進捗度と品質のバランスを保つのが困難。
実装の「進捗度」と「品質」は、トレードオフの関係性にあるのは間違いない。
「進捗度」を意識すれば「リファクタリング」によって「品質」が疎かになりかねないし、
「品質」を意識して「リファクタリング」に時間を割けば、スケジュールが遅延しかねない。
スケジュールの都合上、「リファクタリング」を後回しにするのは止むを得ない。
スケジュールを遅延させずに「リファクタリング」で品質を高めるのは、難しい部分がある。

##バージョン管理が複雑になる。
ブランチを機能毎に切って開発を行っていた場合、作業後にマージを行うのが難しくなる。
また、複数のブランチを切って開発を進めるとなるとマージがさらに厄介になる。
※マージした成果物が後続案件に影響してバグが起きる恐れがあるなど。。
込み入ったマージ問題を解消するには、メインブランチを自分のブランチにマージし
自分のブランチをメインブランチに反映させる作業が発生する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255982/1f3eeb09-e6e8-0617-e5c8-6db31a0a11aa.png)

# ソフトウェア開発プロセスとの関連性
「リファクタリング」は、他の開発プロセスと掛け合わせることによって旨味が生まれる。
込み入ったマージ問題は、継続的インテグレーション(CI)を利用することで解消ができる。
継続的インテグレーション(CI)によって、頻繁に機能ブランチの内容をメインブランチに
反映していればマージの複雑さ(マージの競合等)を軽減させることができます。
「リファクタリング」と「継続的インテグレーション」を掛け合わせることによって
メンバ間の干渉を緩和させることができる。

#考察
「リファクタリング」を提案する際に欠かせないと思ったのは、「正確な見積もり」だと思いました。
「リファクタリング」は、見る人からすれば非生産的な活動です。活動自体が今後の開発にとって
良いことであっても、高コストであれば認めてもらえません。空いた時間を駆使して
ソフトウェアを改善する姿勢が大切だと思いました。

# お願い
「リファクタリング」のことに関して、無知な部分がたくさんありますので
気になる点、ご指摘等ありましたらコメントをよろしくお願いします。