Aikido

Pourquoi utiliser une classe par fichier : améliorer l'organisation et la navigation du code

Lisibilité

Règle

Une classe par dossier.
Plusieurs classes dans a fichier fichier faire code
organisation peu claire et plus plus navigation.

Langues prises en charge : 45+

Introduction

Placer plusieurs classes dans un seul fichier rend difficile la localisation de classes spécifiques lors de la navigation dans une base de code. Les développeurs recherchant UserRepository ne le trouvera pas rapidement s'il est enfoui dans un fichier nommé database.js aux côtés de cinq autres classes. Cela viole le principe de moindre surprise et ralentit le développement, car les membres de l'équipe perdent du temps à rechercher les définitions de classes.

Pourquoi c'est important

Maintenabilité du code : Plusieurs classes par fichier créent des frontières floues entre les responsabilités. Lorsqu'une classe doit être modifiée, les développeurs doivent ouvrir un fichier contenant des classes non liées, ce qui augmente la charge cognitive et le risque de modifier accidentellement le mauvais code.

Navigation et découvrabilité : Les IDE et les éditeurs de texte ont du mal à fournir une fonction "aller à la définition" précise lorsque plusieurs classes partagent un fichier. Les développeurs passent du temps à chercher dans les fichiers plutôt qu'à sauter directement à la classe dont ils ont besoin. Cela se complique dans les grandes bases de code avec des centaines de classes.

Conflits de contrôle de version : Lorsque plusieurs classes partagent un fichier, les modifications apportées à différentes classes par différents développeurs créent des conflits de fusion. Des fichiers séparés permettent un développement parallèle sans surcharge de coordination, car chaque développeur travaille dans son propre fichier.

Exemples de code

❌ 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 };

Pourquoi c'est incorrect : Trois classes de référentiels non liées dans un fichier nommé database.js. Recherche de OrderRepository nécessite de savoir que c'est dans database.js plutôt que OrderRepository.js. Les modifications de fichiers affectent plusieurs classes, créant des conflits de fusion inutiles.

✅ 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;

Pourquoi c'est important : Chaque classe dans son propre fichier rend la navigation prévisible. Les IDE peuvent sauter directement vers OrderRepository.js lors de la recherche de la classe. Les modifications apportées à un dépôt n'affectent pas les autres, éliminant ainsi les conflits de fusion inutiles.

Conclusion

Nommez les fichiers d'après la classe qu'ils contiennent pour une navigation prévisible. Cette convention est adaptée aux grandes bases de code où la recherche rapide de classes spécifiques est cruciale. Les fichiers supplémentaires valent la clarté organisationnelle qu'ils apportent.

FAQ

Des questions ?

Qu'en est-il des petites classes utilitaires ou des classes privées ?

Les petites classes utilitaires utilisées uniquement par une classe parente peuvent rester dans le même fichier si elles sont véritablement des détails d'implémentation. Cependant, si les utilitaires sont réutilisés ou dépassent 20 à 30 lignes, extrayez-les. Les classes privées qui n'existent que pour supporter une seule classe publique constituent des exceptions raisonnables.

Cela s'applique-t-il aux interfaces et aux types TypeScript ?

Les types et interfaces utilisés par une classe peuvent résider dans le même fichier. Cependant, les types partagés utilisés dans plusieurs fichiers doivent se trouver dans leurs propres fichiers de définition de type. La clé est de savoir si la définition n'est utilisée que par ce fichier ou si elle est nécessaire ailleurs.

Qu'en est-il des langages comme Python avec plusieurs classes en pratique courante ?

Les conventions Python diffèrent, mais le principe reste le même : regroupez les classes liées si elles forment un module cohérent, mais évitez de mélanger des classes non liées. Un fichier models.py avec User et UserProfile a du sens. Un fichier utils.py avec vingt classes non liées n'en a pas.

Comment organiser les classes liées comme les classes parentes et enfants ?

Placez-les dans des fichiers distincts au sein du même répertoire. Pour Animal et Dog, utilisez animals/Animal.js et animals/Dog.js. La structure des répertoires montre les relations tout en maintenant une classe par fichier. Cette approche est plus évolutive que le regroupement de classes liées dans un seul fichier.

Que se passe-t-il si l'extraction de classes crée de nombreux petits fichiers ?

De nombreux petits fichiers sont préférables à quelques gros fichiers. Les IDE modernes gèrent des milliers de fichiers efficacement. La navigation dans le système de fichiers est plus rapide que la recherche dans de gros fichiers. La clarté de savoir exactement où se trouve chaque classe l'emporte sur la perception d'un « trop grand nombre de fichiers ».

Sécurisez-vous maintenant.

Sécuriser votre code, votre cloud et votre runtime dans un système centralisé unique.
Détectez et corrigez les vulnérabilités rapidement et automatiquement.

Pas de carte de crédit requise | Résultats du scan en 32 secondes.