Processingで学ぶ 実践的プログラミング専門課程

第27回リファクタリング(1) リファクタリングとは

導入

スポーツをしたことのある人なら、日々トレーニングやフォームの修正が必要なことを痛感していることでしょう。体力は運動を継続しなければ低下しますし、技術は変な癖をつけて狂ってしまいます。一度完成したら、それで将来安泰だ、とはいきません。

ソフトウエアもこれとよく似ています。一度完成したように思えても、業務の変化に対応する必要があります。ハードウエアやOSの変化に伴って、従来のコードでは動かなくなることもあります。

完成したコードであっても日々見直し、正しく動き、メンテナンスしやすい健康な状態を保つ技術が必要です。それが今回から学習するリファクタリングです。本連載の最後を飾るトピックです。

展開

リファクタリング

動いているコードを変更すると、これまでになかったバグを作りこんでしまう可能性があります。その昔「動いているコードを変更してはならない」という格言があったほどです。しかし現在、そんなことでは環境の変化に対応できません。常にコードは変更や修正を加えながら延命していくのです。その際に、コードの変更時にバグを導入しないため、コードを読みやすく理解しやすく書き、そしてコードのメンテナンスを容易にするための知恵や技術が必要です。長い時間をかけてたくさんの先輩プログラマたちが編み出した、知恵や技術をまとめたものがリファクタリングです。

リファクタリングの目的はコードを修正・機能追加することではなく、正しく動いていても不健全なコードを、健全なコードに修正していくことです。リファクタリングのバイブルである『リファクタリング プログラミングの体質改善テクニック』⁠マーチン・ファウラー 著、ピアソン・エデュケーション刊)のP.xviで、次のように定義しています。

リファクタリングとは(マーチン・ファウラーによる)
リファクタリングとは、ソフトウエアの外部的振る舞いを保ったままで、内部の構造を改善していく作業を指します。

これを結城浩さんは、著書『Java言語で学ぶ リファクタリング入門』⁠ソフトバンクパブリッシング刊)で次のようにわかりやすく言い直しています。

リファクタリングとは(結城浩による)
⁠リファクタリング」とは外部から見たプログラムの振る舞いを変えずに、プログラム内部の構造を改善する技法のこと。プログラムの「体質改善」と呼ばれることもある。

この2つの定義文に、リファクタリングの例を見る思いがします。バイブルの文章はコンパクトで的確な言葉が選ばれています。結城さんの文章は、これをほんの少しですが噛み砕くことで、初心者でもわかりやすくなっています。どちらも同じ内容の正しい文章ですが、想定する読者に応じて適切な単語や文体を使用しています。

結城さんはさらにこの定義に先立って、リファクタリングの目的・動機を列挙しています。

  • きれいなソースは読むのが楽、修正するのが楽、デバッグするのが楽、汚いソースは全てが大変。
  • 汚いソースをきれいなソースに書き換えることがリファクタリング

私たちはこれからも、様々なプログラミングの技術を学び、経験を積んで熟練していきます。その学習の一つの要素として、リファクタリングは欠くべからざるものです。

コードの「におい」

いいにおい、嫌なにおい。人の嗅覚は野生動物には及ばないものの、空気中に漂うわずかな分子を検出し、状況判断に役立てられます。これに例えて、ファウラーは「⁠⁠鼻につく』コードを嗅ぎ分け、リファクタリングによって一掃する」⁠P.xvii)のだと述べています。結城さんはこれを「不吉な匂い」と表現しました。どんなコードが匂いを発しているというのでしょうか。

  • 理解しにくい
  • 修正しにくい
  • 拡張しにくい

これらの不自由さを感じたら、コードが鼻についている、不吉な匂いがするということです。かつてGOTO文を多用してわけが分からなくなったコードをスパゲッティコードと呼んだものですが、それこそ異臭ぷんぷんということです。ファウラーはこの匂いの元を一覧表にまとめ、著書やWebサイトに掲載しています。

この一覧すべてを暗記しておくのは大変ですから、折に触れ読み返しましょう。思い当たる悪臭源があったら、早速脱臭に取り掛かりましょう。ピンとくるものを発見して、その度に活用していくのが習得の早道です。

リファクタリングの条件

コードのにおいが感じられるようになったら、そのにおいを取り去るのがリファクタリングの仕事です。適切にリファクタリングされたと判断する際の条件が3つあります。

  1. 外部から見たコードの振る舞いが変わっていないこと
  2. コードの内部構造が改善されていること

これら2つの条件を成立させるためには、次の条件が必要です。

  1. リファクタリングの前後でコードの動きが変わっていないことを保証するためのテストがあり、テストに合格すること

ファウラーは「テストのないリファクタリングは成立しない。テストは『頼みの綱』なのだ」と明言しています。リファクタリングに取りかかる場合には、まずテストコードを書くのだということを覚えてください。

「一度に一つ」の原則

どんな作業でも、確実に成果を積み上げていくためには、一度に複数のことを実行してはいけません。特に科学実験を学習したことのある人は、この原則を叩き込まれたことでしょう。複数の条件を一度に変更してしまうと、予想しない結果が発生した場合の原因特定が困難になります。結局一つひとつ作業を分解してやり直すことになり、二度手間で時間の無駄となります。

リファクタリングも同じです。一度に行う修正は一つだけにしてください。そして、その修正ごとにテストを実施し、外部から見た振る舞いが変わっておらず、正しく動くことを確認するのです。

リファクタリングはオブジェクト指向プログラミングの総合技術

オブジェクト指向プログラミング(以下ではオブジェクト指向と省略)という考え方は、そもそも大規模なコードをいかに取り扱いやすくするかということに端を発しています。ファウラーが「オブジェクト指向自体がリファクタリングに非常に役立つ」⁠P.xviii)と述べているように、リファクタリングを行う人は、オブジェクト指向の各種技術についてある程度の総合的な知識と経験を必要とします。リファクタリングはオブジェクト指向の各種技術を適切に適用していく技術だからです。つまり、リファクタリングはオブジェクト指向の総合技術なのです。Processingを用いて実践的にプログラミングを学ぶこの連載の、最後にリファクタリングを取り扱うのも、学習者の皆さんにそれだけ広いプログラミングの知識を要求するからです。

補足として、リファクタリングはオブジェクト指向プログラミング言語のみに限定した技術ではありません。この連載の範囲では、オブジェクト指向のプログラミング言語であるProcessingを使用していますから、上述のような解説をしました。読者が将来関数型やその他のパラダイム(Paradigm、理論的枠組み)のプログラミング言語を利用する際には、そのパラダイムに応じたリファクタリングを利用することでしょう。その時にも、今回学習を始めたリファクタリングの考え方は必ず役立ちます。

演習

演習1(難易度:easy)

以下の問いに答えてください。

  1. リファクタリングはコードに機能を追加・強化する技術である。⁠はい・いいえ)
  2. 正しく行われたリファクタリングの前後で、外部から見たコードの振る舞いは変わらない。⁠はい・いいえ)
  3. 簡単なリファクタリングであれば、テストは必要ない。⁠はい・いいえ)

まとめ

  • リファクタリングとは、読みやすく、メンテナンスしやすいコードを書く技術であることを学びました。

学習の確認

それぞれの項目で、Aを選択できなければ、本文や演習にもう一度取り組みましょう。

  1. リファクタリングとは何かが理解できましたか?
    1. 理解できた。
    2. 理解できたが、メリットを感じない。
    3. 理解できない。

参考文献

  • 『新装版 リファクタリング―既存のコードを安全に改善する―(OBJECT TECHNOLOGY SERIES⁠⁠マーチン・ファウラー 著、オーム社
    • かつてピアソン・エデュケーション社から出版されていたものの新装版です。リファクタリングのバイブルですから、必携です。
  • 『Java言語で学ぶリファクタリング入門』⁠結城浩 著、ソフトバンククリエイティブ
    • ファウラーのバイブルと併せて読むことをお勧め。著者の解説は一級です。

演習解答

  1. リファクタリングはコードに機能を追加・強化する技術である。⁠いいえ)

    リファクタリングはコードの振る舞いを変更することを目的としません。読みやすく、メンテナンスしやすい健全なコードにすることが目的です。

  2. 正しく行われたリファクタリングの前後で、外部から見たコードの振る舞いは変わらない。⁠はい)

    リファクタリングの前後で、外部から見たコードの振る舞いが変わっていないかを、必ずテストして確かめましょう。

  3. 簡単なリファクタリングであれば、テストは必要ない。⁠いいえ)

    どんな簡単なリファクタリングでも、正しく動いていたコードを変更したわけですし、変更を行うのは不確かな人間ですから、必ずテストを実施しましょう。

おすすめ記事

記事・ニュース一覧