はじめに
汚いとか綺麗とか何?
よく「汚いコード」とか「綺麗なコード」あるいは「美しいコード」なんていう言葉が使われることがある。
汚い、綺麗、美しい、という言葉は元々個人の価値観に基づく感覚的な言葉だ。
処理の羅列であるソースコードに対して感覚的な言葉を使うのは、はたから見ると奇異な行為にうつるだろう。
一方で、プログラマは真剣に綺麗なコードを書くことに努力をしている。彼らは一体何をやっているのか、**「リファクタリング」**という行為から少し考えてみることにする。
想定読者
- リファクタリングって何?って人
- 大事なのはわかるけど進捗を産まないリファクタリングは現実的にできないよって人
リファクタリングって何?
リファクタリングとは一言で言えば「お前の書いたその汚いコード、とりあえず動いているけどもっと綺麗なコードにしよう」ということである。
もう少しかっちりいうと**「コードの振る舞いを変えずに内部構造を変化させること」**だ。
なぜやるの?
僕が思っているリファクタリングをやらなきゃいけないと思う理由は次の三つだ。
1、 変更に強くなりたい
2、 生産性を向上させたい
3、 楽しいコードにしたい!
それぞれ詳しく説明していく。
変更に強くなりたいってどういうこと?
「変更」「修正」「拡張」、システム開発をしていれば必ずよく聞く言葉になる。しかしエンジニアやプログラマの中にはこれらを親の仇のように憎む人もいる。僕たちは本当はこれらを憎みたくない。
変更は歓迎すべきだ。よりよりアイディアが浮かんだってことだから。
修正も歓迎すべきだ。不具合が見つかったんだから。
拡張は大好きだ。システムがもっといいものになるんだから。
変更も、修正も、拡張も新しい知見であり、いつだってwelcomeであるべきだ。
だから僕たちは常に自分のソースコードが変更を受け付けられるようにするべきだ。
変更があったら、即座にどの箇所を変更すればいいか見当がつく。
拡張があったら、どこのクラスに何を拡張すればいいかが見当がつく。
そして僕たちはできるだけ、この変更によって他の機能への影響を最小限にしたい。
生産性を向上したいってどういうこと?
苛立ちを覚えるコードってないだろうか。
やたらと長い関数とか、ほぼコピペのコードが別メソッドに並べられているとか(しかもどこに差分があるのか一見わからない)、1箇所修正したら3箇所修正しないといけないコードとか。
僕たちがこれらにイライラするのは生産性を下げさせられているからだ。
長い関数は読むのに時間を食い、脳のリソースを奪い、結果得られる知識はわずかだったりする。
ほぼコピペのコードが散乱していて1箇所修正するのに3箇所が修正しなければならない日にはストレスを抱える。
僕たちはコードによって生産性を下げられることを憎む。
だからリファクタリングをして生産性をあげたい。
楽しいコードにしたいってどういうこと?
極度に洗練されたプログラムはポエムになる、という言葉がある。
もはや自然言語で記述されたかのように美しいプログラムがそこにあったとして、君はそこに手を加えることに興奮しないだろうか。
一方で、腐臭漂うスパゲッティコードがあって、今日から君はこれの改修を3ヶ月やってくれなんて言われた日には、楽しい気持ちなんて一切ないんじゃないだろうか。
どうせやるなら楽しくやりたい。楽しいコードはリファクタリングから生まれる。
具体的にリファクタリングって何をするの?
どのようにリファクタリングをすると、変更に強い/生産性の高い/楽しいコードになるのか。思いつく限りに書き殴ってみた。
- ロジックの流れが意味不明 → ロジックの流れが明快
- 何が何に影響しているかわからない → 依存関係が明確
- 型がない → 型がある
- 膨大なコード → 小さく区切ったコード
- 何を書いてたか忘れる → 読めば意味のわかるコード
- 名前が体を表していない → 名前が体を表している
- 1箇所の修正するのに何箇所も変更しなければいけない → 1箇所の修正は1箇所でいい
- コピペがある(コピペ元とちょっと違うのかもしれない、という恐怖) → コピペがない。メソッドを使いまわしている。
- 全てが1つのクラスやメソッドに書かれていて、一から読まないと 変更箇所がわからない → 責務を意識したアーキテクチャ
- 頭の痛い問題(バグ)が放置されている → 割れ窓を放置しない
- 再利用するメソッドが使いにくい → 引数と出力が明快
- テストができない → 一目でわかりやすいテストがある
- 同じコードを何度も書いている → 共通化、継承
- 似たようなことを何回もしている → 共通化、継承
- どこに何が書かれているかが明確 → 責務が明快
- ロジックが複雑で何をしているか分からない → シンプルなロジック
- 長くて読むのがだるい → 短い
- ifばっかり → 条件分岐を少なくする
- 一眼で何をしているか分からない → 短いメソッド、適切な命名
- MVCが分けられていない → MVC
- その変数に何が入っているかが想像できない → わかりやすい命名、ドメインモデルの切り出しや統合
これらは抽象化すると3つにまとめられる。
1、可読性 : 読みやすい!
2、高凝縮 : まとまってる!
3、疎結合 : 緩くつながってる!
他にも次のような要素が必要なのが分かる。
- 再利用可能性
- オブジェクト指向(+DDD)
- テスト完備/テスト可能
これらの意識してコードをリファクタリングすることで「変更に強い/生産性の高い/楽しい」コードに近づくことができると思う。
まとめ
- リファクタリングについて説明した
- リファクタリングの動機について説明した
- どんな具体例があるかを列挙した
今回は取り扱わなかったが、リファクタリングは方法論も研究されており、「こういう状態にはこういう手順でリファクタリングをする」のような手順書がまとまっていたりする。興味を持った人はコードスメル、リファクタリングという単語で動画や書籍にあたってみると良いと思います。他にもIDEや高機能エディタにはリネームやメソッド切り出しなどリファクタリングを支援する機能が備わっているので、そちらも触ってみてください。
それでは!