The following two tabs change content below.
アバター画像

メンバー

福岡市博多区でWebシステム開発の受託・ラボ型SES・web集客サービス、3つのWebサービスを提供中

可読性が”エンジニア”に求められる理由

プログラマとして5年目を迎えると、自分のコードが他の開発者に読まれる機会が格段に増えます。
単に機能するだけでなく、保守・拡張しやすいコードを書くことがチームや後輩から期待されるようになります。
コードの可読性はただの美学ではなく、チーム全体の生産性や保守性に直結する重要な要素です。

「書ける」から「読まれる」へ視点が変わるタイミング

新人時代は「動くコードを書く」ことが最優先でした。
これはプログラミングを学びたてのころや、案件に参画した際に誰もがこの思考を先決して実装を行っていたのではないでしょうか。
実際に私もその思いで、実装をしていました。
既存のソースを参考にしながら、右に倣え状態で、なぜこのコードを書いたのか深く考えることなくソースコードを書いていました。
しかし、経験を積むと自分のコードが同僚に読まれ、通話アプリで画面共有をしながら他の開発メンバに説明を行うなど、新人時代に比べて確実に第三者の目に付く機会が増えました
私の場合、あるプロジェクトでリーダーから「君のコードは動くけど、なぜそう実装したのか理解に時間がかかる」と指摘されたことが自分のコードの可動性と向き合う転機でした。

読みにくいコードが開発全体にもたらすコスト

ある大規模プロジェクトでは、前任者の複雑なコードの修正に予定の3倍の時間がかかった経験があります。
システム化、効率化の向上を試みる仕事として、このような事態は避けたいですよね。

プログラマの方であれば一度は読んだことがあるであろう名著、「リーダブルコード」からも一部抜粋させて頂くと、

「コードは書く時間より読まれる時間の方が圧倒的に長い」
「コードは人が読むために書くべき」

とされています。

私が関わったシステムは7年以上運用され、最初のコードは何十回と読み直されています。
特に読みにくいコードは、理解や改修に時間がかかり、バグの温床となることで開発スピードや品質を低下させます。理解しやすさがチーム全体の生産性向上と保守コスト削減に直結すると考えていいでしょう。

私もお世話になった名著「リーダブルコード」を紹介しておきます

レビュワー視点で見る「読みやすいコード」のポイント

コードレビュー可読性向上の重要な機会です。

私が週に何十件ものプルリクエストをレビューするようになって気づいた「読みやすさ」のポイントを紹介します。

コードから「なぜそれが必要なのか」が読み取れるか?

読みやすいコードの最も重要な特性は、「なぜそのコードが存在するのか」が明確なことです。
次の例は全く同じ処理を行う2つのコード。

// 悪い例
public void process() {
    for (User user : userList) {
        if (user.getLastLoginDate().before(threeMonthsAgo) && !user.isAdmin()) {
            user.setStatus(“inactive”);
            notificationService.send(user.getEmail(), “アカウント非アクティブ化のお知らせ”);
        }
    }
}

// 良い例
public void deactivateInactiveUsers() {
    DateTime inactivityThreshold = calculateInactivityThreshold();
    for (User user : userList) {
        if (shouldDeactivateUser(user, inactivityThreshold)) {
            deactivateUser(user);
        }
    }
}

private DateTime calculateInactivityThreshold() {
    // 会社のポリシーで3ヶ月間ログインがないユーザーは非アクティブとする
    return DateTime.now().minusMonths(3);
}

「なぜ」を表す関数名コメントで、ビジネスロジックの意図を明確にします。

命名・粒度・構造が目的に合っているか?

「良いコード、悪いコードで学ぶ設計入門」でも強調されていますが、名前は「意図」を表すべきです。

// 悪い例
function calc(d, t) {
    return d * (1 + t / 100);
}

// 良い例
function calculatePriceWithTax(basePrice, taxRate) {
    return basePrice * (1 + taxRate / 100);
}

また、「関数は一つのことだけを行うべき」という原則も重要です。

コメントはコードと一致しているか?

// ユーザーの年齢が20歳以上かチェックする
if (user.getAge() > 18) {
    allowPurchase();
}

このコメントとコードには乖離があります。コメントは20歳以上と言っていますが、コードは18歳超をチェックしています。自己説明的なコードと必要最小限のコメントを心がけましょう。

「読みにくさ」を構造的に説明できるか?

「このコードは読みにくい」と言うだけでは改善につながりません。
「このメソッドが読みにくい理由は、(1)単一の関数で例外処理・DB操作・通知送信が混在していること、(2)ネストが5段階あり制御フローが追いづらいこと、(3)変数名が抽象的なことです」のように具体的に説明しましょう。
レビュワーとしてだけでなく、自身のコードを客観的に評価し改善点を見つけるためにも、この言語化能力は不可欠です。

よくある”読みにくいコード”の例と改善法

悪い例 vs 良い例

パターン1: 条件式の複雑さ(説明変数の活用)

// 悪い例
if ((user.Type == “premium” || user.Type == “business”) &&
    user.ActiveSubscription &&
    (user.LastPaymentDate > DateTime.Now.AddDays(-30) || user.HasLifetimeAccess) &&
    !user.IsRestricted)
{
    ShowSpecialContent();
}

// 良い例
bool hasPremiumAccess = user.Type == “premium” || user.Type == “business”;
bool hasValidSubscription = user.ActiveSubscription &&
                          (user.LastPaymentDate > DateTime.Now.AddDays(-30) ||
                          user.HasLifetimeAccess);
bool canAccessSpecialContent = hasPremiumAccess && hasValidSubscription && !user.IsRestricted;

if (canAccessSpecialContent)
{
    ShowSpecialContent();
}

変数に意味のある名前をつけることで、複雑な条件式を理解しやすくなります。
こういった「説明変数」は読みやすさを大きく向上させます。

パターン2: マジックナンバー

// 悪い例
if (userPoints > 1000) {
    applyDiscount(0.15);
} else if (userPoints > 500) {
    applyDiscount(0.1);
} else if (userPoints > 100) {
    applyDiscount(0.05);
}

// 良い例
const DISCOUNT_THRESHOLDS = {
    PLATINUM: { points: 1000, rate: 0.15 },
    GOLD: { points: 500, rate: 0.1 },
    SILVER: { points: 100, rate: 0.05 }
};

定数に名前をつければ、数値の意味が明確になり、将来的な変更も容易になります。

改善のポイント解説

  1. 一貫性を保つ

    同じプロジェクト内でコーディングスタイルや命名規則に一貫性があると、読み手はパターンを認識しやすくなります。
  2. 早期リターンでネストを減らす(ガード節)
// 悪い例 – ネストが深い
public void processOrder(Order order) {
    if (order != null) {
        if (order.isValid()) {
            if (order.getItems().size() > 0) {
                // 処理ロジック
            } else {
                throw new Exception(“注文に商品がありません”);
            }
        } else {
            throw new Exception(“無効な注文です”);
        }
    } else {
        throw new Exception(“注文がnullです”);
    }
}

// 良い例 – ガード節でネスト削減
public void processOrder(Order order) {
    if (order == null) {
        throw new Exception(“注文がnullです”);
    }
   
    if (!order.isValid()) {
        throw new Exception(“無効な注文です”);
    }
   
    if (order.getItems().isEmpty()) {
        throw new Exception(“注文に商品がありません”);
    }
   
    // 処理ロジック
}
  1. 適切な抽象化レベルを選ぶ

    低レベルの実装詳細と高レベルのビジネスロジックを混在させないようにしましょう。
  2. テストしやすいコードは読みやすい

    テストしやすいコードは読みやすいコードであることが多いです。なぜなら、テストを書くためには、必然的に関数やクラスの責務が明確になり、依存関係が疎になっている必要があるからです。単体テストを書きながらコードを開発するTDDは、結果として可読性の高いコードを生み出すことが多いです。

最後に

コードの可読性向上は一朝一夕では達成できません。私も数年かけて少しずつ改善してきましたが、今でも日々学びがあります。大切なのは「コードは書く人のためではなく、読む人のために書く」という意識です。常に「未来の自分や他の開発者が、このコードを容易に理解できるか?」と自問自答することが、可読性向上の第一歩です。

「リーダブルコード」の著者は次のように述べています。
「コードは理解しやすくあるべきだ。それはあなたが優れたプログラマーであることを示すためではなく、他の人があなたのコードを理解し、改善し、バグを修正できるようにするためだ。」と。

可読性の高いコードを書くことは、チーム全体の生産性向上やプロジェクトの持続可能性に直結します。この記事が、中堅エンジニアとして次のステップを目指す皆さんのお役に立てば幸いです。