英語 Don't Repeat Yourself.
日本語 繰り返すな。
同じコードを重複して書いてはいけません。
コードの重複でもっとも多いのは、ひとまとまりのロジックを、安易に別の部分にコピー&ペーストして使用した場合です。これにより、同じロジックが複数箇所にばらまかれてしまいます。
また、同じ条件を扱う制御文のブロック群が、様々な場所に重複して現れてしまう場合もあります。これもやはりコピー&ペーストの産物です。条件の分岐が同じで、分岐後の処理が異なる場合、いったんコピー・ペーストしてから、処理の部分のみを書き換えているのです。
「定数リテラル」を直接コードに埋め込んであることも、コードの重複にあたります。同じ意味の定数が複数箇所で使われる場合、定数の指し示す情報が、重複して存在することになるからです。
また、純粋なコードの重複ではありませんが、ただ単にコードをそのまま説明しているコメントも、重複にあたります。コードを母国語に訳しているだけのコメントも、このケースです。
これらの重複を避けるようにコードを書きましょう。また、見つけた時は、速やかに重複を排除するようにしましょう。
コードに重複があると、障害修正や機能追加など、コードを改善していくことが困難になります。具体的には、以下の困難が発生します。
同じようなコードが複数あると、量的に「より多く」なり、質的に「より複雑」になります。そのため、単純に、コードを読む作業が難しくなります。
コードが正確に把握できないと、修正の方針すら立てることができません。
同じようなコードが複数あると、その複数箇所を正確に修正しなければ、全体として整合が取れません。慎重に作業しないと、修正漏れの危険性があります。
また、現在は完全に同じコードでも、もしかしたら今回の修正が必要ない箇所もあるかもしれません。そうなると、それぞれの箇所で、周りのコードを読んで、修正の要・不要を個別に判断しなければなりません。
さらに、現在の重複コードに微差がある場合も、各々の場所でさらにコードを深く読み込まなければなりません。制御文の条件の中身や、制御文の条件数に少しの差があると、難易度はかなり高くなります。最悪、解読不能で修正不能になります。
重複しているようなコードは、たいていの場合、レガシーコードです。つまり、その部分のテストがありません。
一念発起して修正しても、テストがない状態では、新たな障害を生んでしまうリスクがかなり高くなります。
これらの困難を乗り越えて、何とか修正を完了したとしても、複数箇所を力技で修正したコードは、さらに汚くなります。これが積み重なり、全体に蔓延した時、それはもう「修正できないコード」になってしまいます。
コードを「抽象化」することによって、重複を排除しましょう。
コードのロジックを抽象化するには、処理のまとまりに名前を付けて、「関数化」「モジュール化」します。また、データであれば、それに名前を付けて定数を定義します。そして、それらを、繰り返し出てくる部分と置き換えます。
抽象化することによって、以下のメリットが生まれます。
ただし、抽象化を行うには、メンタル面で乗り越えなければならない壁があります。例えば、ロジックを関数にするのであれば、それなりに時間がかかります。また、元の動いていたコードを変えてしまうので、デグレードのリスクが発生します。さらに、率直に面倒です。
しかし、「重複がよくない」ということに、もはや議論の余地はありません。重複を避けておくと、長い目で見ると有利になる、というのが歴史の結論です。リファクタリングに時間をかけてでも、変更によるデグレードのリスク回避に時間を取ってでも、また面倒であっても、重複を排除するようにしましょう。
Copyright © ITmedia, Inc. All Rights Reserved.