ルール
維持 関数 簡潔に
長い 関数 は 難しい 理解 理解し、 テストが 維持 保守が
対応言語: 45以上はじめに
数百行にわたる関数は複数の責任を混在させ、すべての行を読まずにその関数が何をするのかを理解することを困難にします。長い関数は通常、検証、ビジネスロジック、データ変換、エラー処理など、複数の懸念事項をすべて一箇所で処理します。これは単一責任の原則に違反し、既存の動作を壊すことなくテスト、デバッグ、変更が困難なコードを生み出します。
なぜ重要なのか
コードの保守性:長い関数は、開発者がその動作を理解するためにより多くのコンテキストを頭の中に保持することを要求します。すべてのロジックが絡み合っているため、一部を変更すると別の部分を壊すリスクがあります。意図しない副作用を予測することが困難なため、バグ修正はリスクを伴います。
テストの複雑さ: 200行の関数をテストすることは、1つのテストですべての可能なコードパスをカバーすることを意味し、複雑なセットアップと多数のテストケースを必要とします。より小さな関数は、集中的な単体テストで独立してテストできるため、テストスイートをより高速で信頼性の高いものにできます。
コード例
❌ 非準拠:
async function processOrder(orderData) {
if (!orderData.items?.length) throw new Error('Items required');
if (!orderData.customer?.email) throw new Error('Email required');
const subtotal = orderData.items.reduce((sum, item) =>
sum + (item.price * item.quantity), 0);
const tax = subtotal * 0.08;
const total = subtotal + tax + (subtotal > 50 ? 0 : 9.99);
const order = await db.orders.create({
customerId: orderData.customer.id,
total: total
});
await emailService.send(orderData.customer.email, `Order #${order.id}`);
await inventory.reserve(orderData.items);
return order;
}
なぜこれが問題なのか: この関数は、バリデーション、計算、データベース操作、メール、在庫管理を処理します。テストには、すべての依存関係のモックが必要です。税ロジックやバリデーションに変更を加える場合、この関数全体を修正する必要があります。
✅ 準拠済み:
function validateOrder(orderData) {
if (!orderData.items?.length) throw new Error('Items required');
if (!orderData.customer?.email) throw new Error('Email required');
}
function calculateTotal(items) {
const subtotal = items.reduce((sum, item) =>
sum + (item.price * item.quantity), 0);
return subtotal + (subtotal * 0.08) + (subtotal > 50 ? 0 : 9.99);
}
async function createOrder(customerId, total) {
return await db.orders.create({ customerId, total });
}
async function processOrder(orderData) {
validateOrder(orderData);
const total = calculateTotal(orderData.items);
const order = await createOrder(orderData.customer.id, total);
// Non-critical operations in background
emailService.send(orderData.customer.email, `Order #${order.id}`).catch(console.error);
return order;
}これが重要である理由: 各関数は1つの明確な責任を持ちます。 validateOrder() そして calculateTotal() モックなしで独立してテストできます。 createOrder() データベースロジックを分離します。メールおよび在庫操作が注文作成を妨げず、障害は個別に処理されます。
まとめ
追加的な変更を通じてAPIを進化させます。新しいフィールドの追加、新しいエンドポイントの追加、オプションパラメーターの追加などです。破壊的変更が避けられない場合は、APIバージョニングを使用して古いバージョンと新しいバージョンを同時に実行します。古いフィールドは、明確なタイムラインと移行ガイドを提示した上で非推奨とし、その後削除します。

