🌟

ただ動けば良いというコードから可読性の高いコードへ

2023/12/22に公開

可読性の高いコードは保守性の高いコードとも言えるため、開発生産性を高める上でもできる限り読みやすいコードを書くことが、自分にとってもチームにとても大切なことであり重要なことです。

私自身、まだまだ人に誇れるような可読性・保守性の高いコードを書くことはできていないと感じたため、ただ動けば良いというコードから可読性の高いコードを書くことができるエンジニアになるために、リーダブルコードを読み始めました。

可読性の高いコードを書くためには、大きく分けて以下の4項目の改善が重要とのことです。

1. 表面上の改善

名前・コメント・見た目のようなどんな状況下でも適用できる改善

2. ループとロジックの単純化

プログラムのループやロジック、変数を改善して単純化する

3. コードの再構築

肥大化したコードブロックのリファクタリング

4. 選抜テーマ

テストや大きなデータ構造を理解しやすくする方法

今回はこの中から、一番簡単に取りかかれて、なおかつ実際に意識して取り組んでみて効果を感じた項目1の「表面上の改善」についてご紹介したいと思います。

コードの読みやすさの基本定理

他の人が最短時間で理解できるように書かなければならない

自分はすぐに理解できても、他の人が読んで理解するまで時間のかかるようなコードだと、その書いたコードにかかわる部分の修正などがやりづらくなりますし、単純に他の人の作業時間を奪ってしまうことにもなります。

また、わかりにくいコードだと、そのコードに影響のある範囲の理解を誤った解釈で実装されてしまうこともあるので、長期的に見てもあまりよろしくないです。

コードが短ければ良いというわけでも無い

短いコードであることに越したことはないですが、「理解するまでの時間が短くなる」コードが担保できていることが大前提になっていなければ意味がありません。

無理やり短くかっこいい感じのコードを書いたとしても、そのコードが理解しにくい、読みにくいコードになっていたとしたら、それは本当の意味で優れたコードとは言えず、ただの自己満足なコードになってしまいます。

短いコードで書けると気持ちが良いですが、大前提、理解しやすいコードになっているかどうかについて気をつけなければいけないですね。

下記コードよりも

assert((!(bucked = FindBucket(key))) || !bucket->IsBccupied());

↓こちらの方が理解しやすい

bucket = FindBucket(key)
if (bucket != NULL) assert(!bucket->IsOccupied());

場合によっては、コメントで補足しておいた方が理解するまでに時間を短縮できる場合もありますので、必要に応じてコメントを書くことも大切です。

表面上の改善

名前(変数・関数)・コメント・見た目のようなどんな状況下でも適用できる改善

明確な単語を選ぶ

  • getSize のような抽象的に単語は使わない
  • Size だけでは何のサイズなのか理解しずらいです。
    • メモリ消費量なのか? 要素の高さなのか?
    • メモリ消費量なら MemoryBytes のようなより具体的な意味の単語にするのが望ましいです。

抽象的な単語のデメリット

  • 単語が表す範囲が広すぎて、何を指しているのか分かりづらくなります。
  • また、解釈によって様々な意味に捉えられてしまうので間違いが起きやすくもなります。

中身を表す変数名にする

  • retval のような中身の無い変数名を命名しない
    retvalreturn value の略で「戻り値」という意味を表しますが、知らない人が見たら何かわかりません。

  • 下記のようなコードがあったときに、return で返す変数名が retval(戻り値) だと、何かを戻り値として返す変数名なのかということ以外、変数名からは読み取れません。

    const function = (number) => {
      const retval = number + 1.3
      return retval
    }
    

適切な名前の長さ

先ほど抽象的名前はあまりよろしくないという内容のことを書きましたが、実は抽象的な名前を使っても良いケースも存在します。
それはスコープ範囲の狭いケースです。

スコープが狭い範囲で使用する場合

数行程度のスコープで使用されるものであれば、短くて情報量の少ない名前でも良しとされています。

  • 理由
    スコープが狭ければ、変数名のすぐ周辺に、その変数を表す値・初期値・変数の型など、情報がたくさんあり、そこから読み解けるため、短くて情報の少ない変数名でも問題ありません。

    ただしスコープ範囲が広いケースは例外です。

スコープが広い範囲で使用する場合

長くても良いので、名前から何を意味するものか分かる具体的な名前にして、情報を詰め込む。

  • 理由
    スコープが広いと、変数名以外の変数名に関連する情報を得ることができないので、情報量の少ない変数名だと理解しにくくなってしまいます。

    なので、スコープが広い範囲で使う変数であれば、具体化するために多少長い命名になっても良いので、名前から中身の情報を理解することができる「具体的な名前」にすることが望ましいです。

複雑な条件判定式は要約変数を使用する

複雑な条件判定式は要約変数を利用することで、可読性がとても高まります。

  • ダメな例

    const MyComponent = ({ user, system }) => {
      return (
        <div>
          {user.isLoggedIn && user.hasPermission('edit') && !user.isLockedOut && system.isFeatureEnabled('edit') ? (
            <EditComponent />
          ) : (
            <ViewComponent />
          )}
        </div>
      );
    }
    

    この例は、複数の条件式がたくさんあり、ぱっと見で何を判断しようとしているのか分かりにくいです。


  • 良い例

    const MyComponent = ({ user, system }) => {
      const canEdit = user.isLoggedIn && user.hasPermission('edit') && !user.isLockedOut && system.isFeatureEnabled('edit');
    
      return (
        <div>
          {canEdit ? <EditComponent /> : <ViewComponent />}
        </div>
      );
    }
    

    こちらのように canEdit という要約変数を使うことで、ユーザーが編集機能を使えるかどうかの条件を簡潔に表現することができます。
    また、同じような条件判定式があった場合も、取りまわすことが容易なためとても便利です。

まとめ

可読性の高いコードに改善するための学びの共有は以上になります。
どれも基本的な内容にはなりますが、この基本を抑えるだけでも、何も考慮しなかった時と比べると可読性の高さが変わるため、ぜひ意識して取り組んでみてください。

ゲームエイトテックブログ

Discussion