認知負荷理論から読み解く「可読性の高いコード」の条件とは

認知負荷理論についてご紹介します。認知負荷理論の観点から読みにくい資料、コードとは何か、掘り下げていきます。

はじめに

 

日々の業務において、コードや資料を読む際に「読みにくい」「理解に時間がかかる」と感じることはないでしょうか。

なぜ読みにくいコードが生まれてしまうのか。その原因を掘り下げていくと、「綺麗なコード」か「汚いコード」かという判断基準が、個人の感覚や経験によって異なっているからではないかと考えました。

本記事では、この課題を解決するために「認知負荷理論」の観点を紹介します。なぜ特定の資料やコードが脳に負担をかけるのかを理解することで、根本的に脳に負担のかからない「可読性の高いコードや資料」を書けるようにしていきましょう。

認知負荷理論の3つの負荷

認知負荷理論とは、人間のワーキングメモリ(短期記憶)には限界があるという前提に基づき、情報処理時の脳への負担を分類する理論です。この理論では、負荷を以下の3つに定義しています。

  1. 内的負荷:解こうとする問題そのものが持つ複雑さによる負荷。
  2. 外的負荷:解こうとする問題の「見え方」によって生じる負荷。
  3. 学習関連負荷:構造を深く理解し、長期記憶として定着させるために必要な負荷。


例えばこれを料理に当てはめると…

  • 内的負荷:料理そのものの難しさ(例:「オムライスの卵をきれいに包む」という調理自体の複雑さ)
  • 外的負荷:レシピの「見せ方・読みづらさ」によるストレス
  • 学習関連負荷:料理の「仕組みやコツ」を理解して、次回に応用できるようにする脳の働き

可読性を高めるには


総認知負荷 = 内的負荷 + 外的負荷 + 学習関連負荷 ≦ 脳の処理限界

ソフトウェア開発において、①の「内的負荷」は実装すべき仕様そのものに起因するため、これを減らすことは困難です。また、③の「学習関連負荷」は、システムの全体像を長期的な目線で学習・定着させるために、ある程度確保しておくべき重要な負荷です。

したがって、②の「外的負荷(見え方による負荷)」をいかに減らせるかという点が重要になります。見え方を改善することで、この外的負荷は大幅に削減することが可能です。

内的負荷は減らせない以上、見え方を工夫して外的負荷を極力減らし、そこで余った脳のメモリを学習関連負荷へと回すことが、「可読性の高いコード」への近道となります。

実際のコード例

整理前の状態

以下は整理前の状態です。情報が整理されておらず、コードの意図を読み解くための外的負荷が非常に高くなっています。

public class OrderProcessor {
    public void process(Order__c o) {
        if (o.IsActive__c) {
            if (o.Amount__c >= 5000) {
                if (o.IsPremium__c) {
                    o.Discount__c = o.Amount__c * 0.2;
                    o.Shipping__c = 0;
                } else {
                    o.Discount__c = o.Amount__c * 0.1;
                    o.Shipping__c = 500;
                }
            }
        }
    }
}

整理後の状態

そしてこちらが、各理論をもとに書き換えや追加を行い、整理した後の状態です。外的負荷が取り除かれたことで、読み手は仕様そのものの理解にメモリを集中できるようになります。

public class OrderProcessor {
    private static final Decimal QUALIFY_AMOUNT = 5000;

    public void process(Order__c o) {
        if (!o.IsActive__c) return; 

        Decimal rate = o.IsPremium__c ? 0.20 : 0.10;
        Decimal fee  = o.IsPremium__c ? 0    : 500;

        o.Discount__c = (o.Amount__c >= QUALIFY_AMOUNT) ? o.Amount__c * rate : 0;
        o.Shipping__c = fee;
    }
}

修正ポイントの解説

  • if (!o.IsActive__c) return;
    IsActive__cが「false」となる時点で処理を終了させ、無駄なif文の階層を減らすことができます。外的負荷の削減
  • Decimal rate = o.IsPremium__c ? 0.20 : 0.10;
    Decimal fee = o.IsPremium__c ? 0 : 500;
    rate(割引率)とfee(送料)を変数として定義することで数値の持つ意味を伝えることができ、コード内での再利用も可能になります。
    またrateとfeeを並列で定義することで「プレミアムと一般で何が違うのか」というビジネスの仕組みも直感的に伝えることができます。学習関連負荷の削減<
    変数内で「プレミアム」か「一般」かの判別をすることで無駄なif文の階層も減らすことができます。外的負荷の削減<
  • o.Discount__c = (o.Amount__c >= QUALIFY_AMOUNT) ? o.Amount__c * rate : 0;
    変数内で条件によって値を変えることで無駄なif文の階層を減らすことができます。外的負荷の削減<

ドキュメント作成や仕様定義への応用事例

今回プロジェクトでは仕様の洗い出し時にこの観点を使用しました。今までは「グラフと数値など関連する情報は物理的に近くに配置すべき」や「1スライド1メッセージ」などただの知識として記憶されていたところが、認知負荷理論を踏まえて作業に取り組むと主体的に外的負荷、学習関連負荷の観点から不足している部分を洗い出すことができ、レビュー時の指摘事項を削減することができました。

おわりに

「可読性の高いコード」とは、単に見た目が美しいコードではなく、「読み手の脳のメモリを無駄遣いさせないコード」であると言えます。

今後の開発やコードレビューにおいては、個人の感覚である「綺麗・汚い」ではなく、「このコードは無駄な外的負荷を生んでいないか?」という客観的な視点を持つことが、チーム全体の生産性向上と保守性の担保に繋がると考えています。

参考文献