Regola
Regola classe per file.
Più classi in un singolo file make codice
organizzazione poco chiaro e più difficile da navigazione.
Lingue supportate: 45+Introduzione
Inserire più classi in un unico file rende difficile individuare classi specifiche durante la navigazione nel codice. Gli sviluppatori che cercano Repository utenti non lo troverai subito se è nascosto in un file chiamato database.js insieme ad altre cinque classi. Ciò viola il principio della “minima sorpresa” e rallenta lo sviluppo, poiché i membri del team perdono tempo a cercare le definizioni delle classi.
Perché è importante
Manutenibilità del codice: la presenza di più classi in un unico file rende poco chiari i confini tra le responsabilità. Quando è necessario modificare una classe, gli sviluppatori devono aprire un file contenente classi non correlate, aumentando così il carico cognitivo e il rischio di modificare accidentalmente il codice sbagliato.
Navigazione e reperibilità: gli IDE e gli editor di testo faticano a fornire una funzione "vai alla definizione" accurata quando più classi condividono lo stesso file. Gli sviluppatori perdono tempo a cercare all’interno dei file invece di passare direttamente alla classe di cui hanno bisogno. Questo problema si aggrava nei codici di grandi dimensioni con centinaia di classi.
Conflitti nel controllo di versione: quando più classi condividono un unico file, le modifiche apportate a classi diverse da sviluppatori diversi generano conflitti di unione. L'utilizzo di file separati consente lo sviluppo parallelo senza oneri di coordinamento, poiché ogni 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é è sbagliato: Tre classi di repository non correlate in un unico file denominato database.js. Ricerca di OrderRepository richiede di sapere che si trova in database.js piuttosto che OrderRepository.js. Le modifiche al file interessano più classi, creando conflitti di unione 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é è importante: Il fatto che ogni classe sia contenuta in un proprio file rende la navigazione più intuitiva. Gli IDE possono passare direttamente a OrderRepository.js durante la ricerca della classe. Le modifiche apportate a un repository non influiscono sugli altri, eliminando così i conflitti di unione superflui.
Conclusione
Assegnate ai file il nome della classe che contengono, per garantire una navigazione intuitiva. Questa convenzione risulta particolarmente utile nei codici di grandi dimensioni, dove è fondamentale poter individuare rapidamente classi specifiche. I file aggiuntivi valgono la pena per la chiarezza organizzativa che garantiscono.

