始めに
お久しぶりです、るんるんです。
エンジニアの皆さんはリファクタリングについてどうお考えでしょうか。
私は面倒臭い印象しかありません。そして実際にやってみて、面倒臭かったです。
新卒エンジニア一年目の6月に2件ほどリファクタリングを任され、その時の苦悩は今でも覚えているものです。
そこで、その苦悩から生まれた肥やしを披露したいと思います。
ある日突然上司から「ここリファクタリングしといて!」と言われて、「...辞めさせてもらいます」と言わないで済みます(多分)
リファクタリングとは
そもそも
そもそもから参りましょう。リファクタリングとはなんぞやについてです。
IT用語辞典 e-wordsでは以下のように紹介されています
リファクタリング(refactoring)とは、ソフトウェア開発で、プログラムの動作や振る舞いを変えることなく、内部の設計や構造を見直し、コードを書き換えたり書き直したりすること。
「プログラムの動作や振る舞いを変えることなく」とありますが、これがリファクタリングの根幹です。リファクタリング前後で同じ挙動を担保しつつ変更を行うのです。
「ユーザーからは変更を感知できない変更」とも言い換えることができます。
そのため、バグ修正はリファクタリングとは言わないのです。
エントロピー増大の法則
リファクタリングしたところで結果は同じなのに、元々動いているプログラムをわざわざ一度壊して再構築するのでしょうか。
エンジニアが「リファクタリングしたい!」という衝動に駆られる瞬間は
- コードが読みづらい...
- コードの構造が複雑すぎる...
- パフォーマンスが低い...
などが挙げられるでしょうか。
なぜこのような瞬間を迎えるのでしょうか。
その答えは、ソースコードにエントロピー増大の法則なるものが働きます。
小難しい話が始まりますが...
エントロピー増大の法則とは、「時間経過や量の増加により物事の煩雑さが増大する」ことを指します(元々は熱力学の考え方で、そこからプログラミングにもこの考え方が浸透しました)。
ソースコードの量が増えれば増えるほど、複雑さが増していく。自然な出来事です。
放置することも可能ですが追加開発の際にその複雑さが邪魔をして、開発スピードに大きく影響を及ぼします。
リファクタリングは先行投資のようなもので、リファクタリングの行為自体に価値を見出しにくいですが、今後の開発で複利の力が働きます。
スターターマインドデッキ
前置きが長くなってしまいました...
ここからはそんな面倒臭いくせに大事な作業であるリファクタリングに臨む際のマインドセット 「リファクタリングスターターマインドデッキ」 を紹介します。
このマインドカードを持ち合わせることで、リファクタリングの際に失敗することなく、タスクを終えることができると思います。
1. 羅針盤を得る ~リファクタリングをする意義を知る~
リファクタリングに臨む際に、まずはなぜやるのかを明確にしましょう。
「可読性が向上する」と言うような抽象的な捉え方ではまだ甘いです。
一例ですが、こんな感じでしょうか
可読性を向上させる → これから入ってくる新人エンジニアがコードを読んだ時に、理解スピードが上がる!
「リファクタリングをすると未来にどんな良いことがあるのだろう」と想像しながら作業を行うことで、自然と目標が明確になると思います。
2. 敵を知る者は百選危うからず ~ソースコードの理解~
リファクタリングをする時は、ソースコードの理解が不可欠です。
コツとしては、一旦細かなロジックの理解は無視することです。まずは全体感を掴み、どこがなんのために存在するかを把握します。
全体感を掴んだ後はコードの背景を理解することです。
- なぜこのコードは存在しているのか
- なぜこのコードはこんな構造なのか
- なぜこのコードはこのロジックなのか
といったところでしょうか。
これらを理解するには、実装者に聞くのが一番早いです。
実装者が退社している可能性もありますが、なるべく関係ありそうな人に聞いて回りましょう。
コードの背景を知ることで、破壊して良い場所なのか等、リファクタリングを行う際の解像度が高まります。
3.来た時よりも美しく ~破壊と再構築~
リファクタリングをするとは、「破壊と再構築」なのです。
再構築の結果目標が 「来た時よりも美しく」 です。
遠足を思い出しますね。この考えは、リファクタリングにも有効です。
コードを破壊して再構築する際に、破壊前よりも美しくする事を念頭に作業を行います。と同時に破壊前と挙動が変わらないことを担保することも忘れてはいけません。
# 挙動が変わってしまっている
A → A'
A → B
# 来た時よりも美しい!!
A → A(Clear and Simple)
挙動が変わっていないかを担保するには、ユニットテストが有効です。
ソースコードは変更したが、ユニットテストで挙動が同じであること、ロジックが妥当であることを担保するのです。
コードの構造を変えることで、該当箇所のユニットテストが全て失敗します。ユニットテストに変更を加える場合は、あくまで挙動が同じであることを担保しつつテストの修正を行わなければなりません(ここが私は一番難しかったです)。
結び
今回は、私がエンジニア1年目に経験したリファクタリング業務を思い返してみて特に大事なマインド、スタンスを書き出してみました。
リファクタリングする際に少しだけでも参考になると幸いです。