ルール
1ファイルに つき 1クラス。
単一ファイルに 複数の クラスが あると、 コードの
整理が 不明瞭になり、 ナビゲートが 困難になります。
サポート言語: 45+はじめに
単一ファイルに複数のクラスを配置すると、コードベースをナビゲートする際に特定のクラスを見つけるのが困難になります。開発者が検索する際に UserRepository という名前のファイルに埋もれている場合、すぐには見つけられないでしょう。 database.js 他の5つのクラスと並んでいます。これは最小驚きの原則に反し、チームメンバーがクラス定義を探すのに時間を浪費するため、開発を遅らせます。
なぜ重要なのか
コードの保守性:1ファイルあたりのクラスが複数あると、責務間の境界が不明確になります。あるクラスの変更が必要な場合、開発者は無関係なクラスを含むファイルを開く必要があり、認知負荷が増大し、誤って間違ったコードを変更するリスクが高まります。
ナビゲーションと発見可能性: 複数のクラスがファイルを共有している場合、IDEやテキストエディタは正確な「定義へ移動」を提供することに苦労します。開発者は、必要なクラスに直接ジャンプするのではなく、ファイル内を検索するのに時間を費やします。これは、数百のクラスを持つ大規模なコードベースでさらに複雑になります。
Version control conflicts: 複数のクラスが1つのファイルを共有する場合、異なる開発者による異なるクラスへの変更はマージの競合を引き起こします。ファイルを分離することで、各開発者が自身のファイルで作業するため、調整のオーバーヘッドなしに並行開発が可能になります。
コード例
❌ 非準拠:
// database.js
class UserRepository {
async findById(id) {
return db.users.findOne({ id });
}
}
class OrderRepository {
async findByUser(userId) {
return db.orders.find({ userId });
}
}
class ProductRepository {
async findInStock() {
return db.products.find({ stock: { $gt: 0 } });
}
}
module.exports = { UserRepository, OrderRepository, ProductRepository };
誤っている理由: という名前の1つのファイルにある3つの関連性のないリポジトリクラス database.js。検索中 OrderRepository それがどこにあるかを知る必要があります。 database.js ~ではなく OrderRepository.js。ファイル変更が複数のクラスに影響を与え、不要なマージコンフリクトを引き起こします。
✅ 準拠済み:
// UserRepository.js
class UserRepository {
async findById(id) {
return db.users.findOne({ id });
}
}
module.exports = UserRepository;
// OrderRepository.js
class OrderRepository {
async findByUser(userId) {
return db.orders.find({ userId });
}
}
module.exports = OrderRepository;
// ProductRepository.js
class ProductRepository {
async findInStock() {
return db.products.find({ stock: { $gt: 0 } });
}
}
module.exports = ProductRepository;
これが重要である理由: 各クラスを独自のファイルにすることで、ナビゲーションが予測可能になります。IDEは直接ジャンプできます。 OrderRepository.js クラスを検索する際。あるリポジトリへの変更は他のリポジトリに影響せず、不要なマージ競合を排除します。
まとめ
予測可能なナビゲーションのために、ファイル名には含まれるクラスの名前を付けます。この慣習は、特定のクラスを素早く見つけることが重要な大規模なコードベースにも対応できます。ファイルが増えることよりも、それらが提供する組織的な明確さの方が価値があります。

