0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

自己文書化コード(Self-documenting Code)とは?— 読みやすく、保守しやすいコードの書き方

Posted at

コードを初めて見たとき、すぐに理解できましたか?多くの開発者が、他人のコードを読み解くのに苦労しています。その解決策の一つが「自己文書化コード(Self-documenting Code)」です。これは、コメントに頼らず、コード自体がその目的や動作を明確に伝えるように書かれたコードのことです。

🧩 例:改善前のコード

以下は、ユーザーアカウントを作成するJavaScript関数の例です。一見シンプルですが、改善の余地があります。

async function createUser(user) {
    if (!validateUserInput(user)) {
        throw new Error('u105');
    }

    const rules = [/[a-z]{1,}/, /[A-Z]{1,}/, /[0-9]{1,}/, /\W{1,}/];
    if (user.password.length >= 8 && rules.every((rule) => rule.test(user.password))) {
        if (await userService.getUserByEmail(user.email)) {
            throw new Error('u212');
        }
    } else {
        throw new Error('u201');
    }

    user.password = await hashPassword(user.password);
    return userService.create(user);
}

このコードでは、エラーコードが数字で表されており、何を意味するのか直感的に分かりません。また、パスワードのバリデーションロジックが関数内に直接書かれており、再利用性や可読性が低下しています。

🛠️ 改善ポイント

1. 名前付き定数の使用

エラーコードを意味のある名前の定数に置き換えることで、コードの意図が明確になります。([Lack of Imagination][2])

const err = {
    userValidationFailed: 'u105',
    userExists: 'u212',
    invalidPassword: 'u201',
};

2. 単一責任の原則

パスワードのバリデーションロジックを別関数に分離することで、コードの再利用性と可読性が向上します。

function isPasswordValid(password) {
    const rules = [/[a-z]{1,}/, /[A-Z]{1,}/, /[0-9]{1,}/, /\W{1,}/];
    return password.length >= 8 && rules.every((rule) => rule.test(password));
}

これらの改善を適用した createUser 関数は以下のようになります。([Lack of Imagination][2])

async function createUser(user) {
    if (!validateUserInput(user)) {
        throw new Error(err.userValidationFailed);
    }

    if (isPasswordValid(user.password)) {
        if (await userService.getUserByEmail(user.email)) {
            throw new Error(err.userExists);
        }
    } else {
        throw new Error(err.invalidPassword);
    }

    user.password = await hashPassword(user.password);
    return userService.create(user);
}

3. 短絡評価の活用

短絡評価を使用することで、条件分岐を簡潔に表現できます。([Lack of Imagination][2])

function throwError(error) {
    throw new Error(error);
}

async function createUser(user) {
    validateUserInput(user) || throwError(err.userValidationFailed);
    isPasswordValid(user.password) || throwError(err.invalidPassword);
    !(await userService.getUserByEmail(user.email)) || throwError(err.userExists);

    user.password = await hashPassword(user.password);
    return userService.create(user);
}

このように書くことで、ネストが減り、コードの流れが直線的になります。

4. 型注釈の追加

JSDocを使用して型注釈を追加すると、IDEや静的解析ツールがコードを理解しやすくなります。

/** @typedef {{ id?: number, birthDate: Date, email: string, password: string }} User */

/**
 * Creates a user and returns the newly created user's id on success
 * @param {User} user
 * @returns {Promise<any>}
 */
async function createUser(user) {
    validateUserInput(user) || throwError(err.userValidationFailed);
    isPasswordValid(user.password) || throwError(err.invalidPassword);
    !(await userService.getUserByEmail(user.email)) || throwError(err.userExists);

    user.password = await hashPassword(user.password);
    return userService.create(user);
}

これにより、関数の入力と出力が明確になり、他の開発者がコードを理解しやすくなります。

✅ まとめ

自己文書化コードを実現するためのポイントは以下の通りです。

  • 意味のある名前付き定数を使用する
  • 関数は単一の責任を持つようにする
  • 短絡評価を活用してコードを簡潔にする
  • 型注釈を追加してコードの意図を明確にする

これらを実践することで、コメントに頼らずとも、コード自体がその目的や動作を明確に伝えるようになります。結果として、コードの可読性と保守性が向上し、開発効率の向上につながります。


元記事はこちら:
🔗 Self-documenting Code - Lack of Imagination

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?