Regola
Una classe per file.
Più classi in un singolo file rendono l'organizzazione
del codice poco chiara e difficile
da navigare.
Linguaggi supportati: 45+Introduzione
Inserire più classi in un unico file rende difficile trovare classi specifiche durante la navigazione in una codebase. Gli sviluppatori che cercano UserRepository non la troveranno rapidamente se è sepolta in un file chiamato database.js insieme ad altre cinque classi. Questo viola il principio della massima sorpresa e rallenta lo sviluppo poiché i membri del team perdono tempo a cercare le definizioni delle classi.
Perché è importante
Manutenibilità del codice: Più classi per file creano confini poco chiari tra le responsabilità. Quando una classe richiede una modifica, gli sviluppatori devono aprire un file contenente classi non correlate, aumentando il carico cognitivo e il rischio di modificare accidentalmente il codice sbagliato.
Navigazione e individuabilità: Gli IDE e gli editor di testo faticano a fornire un "vai alla definizione" accurato quando più classi condividono un file. Gli sviluppatori perdono tempo a cercare all'interno dei file anziché saltare direttamente alla classe di cui hanno bisogno. Questo problema si amplifica nelle codebase di grandi dimensioni con centinaia di classi.
Conflitti di controllo versione: Quando più classi condividono un file, le modifiche a classi diverse da parte di sviluppatori differenti creano conflitti di merge. File separati consentono uno sviluppo parallelo senza sovraccarichi di coordinamento, poiché ciascuno sviluppatore lavora sul proprio file.
Esempi di codice
❌ Non conforme:
// 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 };
Perché è errato: Tre classi di repository non correlate in un unico file chiamato database.js. La ricerca di OrderRepository richiede di sapere che si trova in database.js anziché in OrderRepository.js. Le modifiche al file influiscono su più classi, creando conflitti di merge non necessari.
✅ Conforme:
// 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;
Perché questo è importante: Ogni classe nel proprio file rende la navigazione prevedibile. Gli IDE possono saltare direttamente a OrderRepository.js quando cercano la classe. Le modifiche a un repository non influiscono sugli altri, eliminando conflitti di merge superflui.
Conclusione
Assegna ai file il nome della classe che contengono per una navigazione prevedibile. Questa convenzione è scalabile per codebase di grandi dimensioni in cui è fondamentale trovare rapidamente classi specifiche. I file aggiuntivi valgono la chiarezza organizzativa che offrono.

