誤解を防ぐ変数・関数名の付け方 - 明確で一貫性のある命名でバグを減らす方法
理解しやすいコードを書くためには、誤解されない関数名や変数名をつけることが大切である。
あいまいな名前を避ける
曖昧な言葉を使うと、誤解されるコードになる。
// 曖昧な例
const result = database.allRecords.filter(record => record.year <= 2025);
この場合のfilter
で考えられる動作として以下の2つが考えられる:
- 「 year <= 2025 」の条件に一致するオブジェクト
- 「 year <= 2025 」の条件に一致しないオブジェクト
名前が曖昧だと、開発者によって解釈が異なる可能性がある。このような場合は、より明確な名前を使うべきである。例えば:
// より明確な例
const result = database.allRecords.where(record => record.year <= 2025);
// または
const matchingRecords = database.allRecords.filter(record => record.year <= 2025);
限界値を含むかどうかを明確にする
例えば、範囲を表す時に「limit」という言葉は曖昧である。
// これは10個以上でエラーなのか、11個以上でエラーなのか?
const CART_TOO_BIG_LIMIT = 10;
if (shoppingCart.getItemCount() >= CART_TOO_BIG_LIMIT) {
throw new Error("カート内のアイテムが多すぎます。");
}
より明確にするには「min」や「max」などの言葉を使う:
const MAX_ITEMS_IN_CART = 10;
if (shoppingCart.getItemCount() > MAX_ITEMS_IN_CART) {
throw new Error("カート内のアイテム数が上限を超えています。最大: " + MAX_ITEMS_IN_CART);
}
範囲の表現には適切な名前を
範囲を表す変数名も慎重に選ぶべきである。
閉区間(両端を含む)には「first」と「last」を使う
変数名 | 意味 |
---|---|
first | 範囲の開始位置(含む) |
last | 範囲の終了位置(含む) |
例えば、配列のインデックス[1, 3]は以下のように表現できる:
first | last | ||||
---|---|---|---|---|---|
インデックス | 0 | 1 | 2 | 3 | 4 |
要素 | B | C | D |
この場合:
- first = 1 (Bを含む)
- last = 3 (Dを含む)
// [first, last]の範囲(両方含む)
function getElementsInRange(array, { first = 1, last = 3 }) {
// firstからlastまでの要素を取得(両端を含む)
return array.slice(first, last + 1); // last + 1 とすることで last も含める
}
// 使用例
const letters = ['A', 'B', 'C', 'D', 'E'];
const result = getElementsInRange(letters, { first: 1, last: 3 });
console.log(result); // ['B', 'C', 'D']
半開区間(始点を含み、終点を含まない)には「begin」と「end」を使う
変数名 | 意味 |
---|---|
begin | 範囲の開始位置(含む) |
end | 範囲の終了位置(含まない) |
例えば、配列のインデックス[1, 4)は以下のように表現できる:
begin | end | ||||
---|---|---|---|---|---|
インデックス | 0 | 1 | 2 | 3 | 4 |
要素 | B | C | D |
この場合:
- begin = 1 (Bを含む)
- end = 4 (Eを含まない)
// [begin, end)の範囲(beginは含み、endは含まない)
function getElementsInOpenRange(array, { begin = 1, end = 4 }) {
// beginからend-1までの要素を取得
return array.slice(begin, end); // JavaScriptのsliceはendを含まないので調整不要
}
// 使用例
const letters = ['A', 'B', 'C', 'D', 'E'];
const result = getElementsInOpenRange(letters, { begin: 1, end: 4 });
console.log(result); // ['B', 'C', 'D']
ブール値の変数名
ブール値の変数名は特に注意が必要である。
// 曖昧な例 - これは「パスワードを読み込む必要がある」のか「パスワードが読み込まれた」のか不明
let readPassword = true;
ブール値には「is」「has」「can」「should」などのプレフィックスを付けるとよい:
// 明確な例
const isAuthenticated = true;
const hasPermission = false;
const canEdit = true;
const shouldRetry = false;
「xxxFlg」という命名パターンも注意が必要である:
// 曖昧な例
let deleteFlg = true; // これは「削除済み」なのか「削除対象」なのか不明確
let activeFlg = false; // 否定の状態が何を意味するのか分かりにくい
より明確な命名方法:
// 明確な例
const isDeleted = true; // 「削除済み」という状態が明確
const isActive = false; // 「アクティブではない」ことが明確
const shouldDelete = true; // 「削除すべき」という意図が明確
また、否定形よりも肯定形を使うほうが理解しやすくなる:
// 悪い例
const disableSsl = false;
const notCompleted = true;
const deleteFlg = false; // 「削除フラグがオフ」という二重否定的な意味になる
// 良い例
const useSsl = true;
const isInProgress = true;
const isActive = true; // 「アクティブである」という肯定的な意味
期待に沿った名前をつける
関数名が実際の動作と一致していることも重要である。
// getMeanという名前だが、実際には計算処理が必要
class Statistics {
getMean() {
// すべてのサンプルを反復処理して計算するので重い処理
return this.samples.reduce((sum, value) => sum + value, 0) / this.samples.length;
}
}
この場合、「get」は通常、軽量な操作を意味する。しかし実際には計算処理が必要なので、「compute」を使うほうが適切である:
class Statistics {
computeMean() {
// 計算処理が必要なことが名前から明確
return this.samples.reduce((sum, value) => sum + value, 0) / this.samples.length;
}
}
単位や状態を名前に含める
変数名に単位や状態を含めると、誤解を防ぐことができる:
// 悪い例
function startProcess(delay) { /* ... */ }
function createCache(size) { /* ... */ }
function throttleDownload(limit) { /* ... */ }
// 良い例
function startProcess(delayMs) { /* ... */ }
function createCache(sizeMb) { /* ... */ }
function throttleDownload(maxKbps) { /* ... */ }
データの状態を示す場合:
// 悪い例
const password = "abc123";
const comment = "<p>ユーザーコメント</p>";
const html = "<div>コンテンツ</div>";
// 良い例
const plaintextPassword = "abc123";
const unescapedComment = "<p>ユーザーコメント</p>";
const htmlUtf8 = "<div>コンテンツ</div>";
まとめ
良い名前を選ぶことは、コードの品質に大きく影響する。誤解されない名前をつけることで:
- チームメンバーがコードを理解しやすくなる
- バグの発生リスクが下がる
- 将来のメンテナンスがしやすくなる
名前を選ぶときは、「他の開発者がこの名前を見たとき、誤解なく理解できるか?」と自問するとよい。
参考文献
- 『リーダブルコード』(Dustin Boswell, Trevor Foucher 著、角征典 訳、オライリー・ジャパン、2012年)