yutna/oo-design

À utiliser lors du démarrage d'un nouveau module, d'une fonctionnalité ou d'un système dans une base de code orientée objet, pour dimensionner la conception ou en cas d'incertitude sur la règle objet applicable.

Qu'est-ce que oo-design ?

Cette compétence fournit un ensemble complet de règles de conception orientée objet (OO) pour aider les développeurs à prendre des décisions architecturales éclairées. Elle couvre tout le processus de conception, depuis l'identification de la quantité de conception nécessaire pour une tâche donnée (par exemple, une simple méthode vs un nouveau système) jusqu'à l'application d'un cycle de conception détaillé. Le cycle guide l'utilisateur à travers la définition du comportement dans le langage du domaine, l'identification des limites de cohérence, le placement de la logique métier, la conception des messages, l'inversion des dépendances, la dénomination, et la révision des résultats par rapport aux signaux d'alarme. La compétence introduit également son propre système de classification des règles (Règle, Défaut, Jugement), ainsi qu'une vaste table de correspondance entre symptômes de conception courants et les compétences spécifiques recommandées pour les résoudre (par exemple, assigner des responsabilités, encapsuler l'état, modéliser les agrégats). Destinée aux codebases orientées objet, cette compétence sert de guide de référence complet, garantissant que les décisions de conception sont cohérentes, maintenables et alignées avec les principes de la conception pilotée par le domaine (DDD).

Compatible avec✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/yutna/object-oriented-design-skills/tree/HEAD/plugins/core/skills/oo-design

Installed? Explore more Développement et programmation skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Conception Orientée Objet

Vue d'ensemble

Ce pack contient des règles de conception pour les codebases écrites dans un style orienté objet, et non des conseils universels. Les conventions écrites d'un projet priment sur ce pack. Suivez l'idiome du module que vous modifiez. Cette compétence dimensionne la tâche et nomme la compétence appropriée.

Chargez la compétence que cet index nomme avant de répondre : ses règles et ses exemples s'y trouvent, pas ici.

Quelle quantité de conception une tâche nécessite

TâcheUtiliserIgnorer
Une réponse utilisée une fois, puis jetéeRienTout
Une méthode dans une classe existanteSon nom et son contratRemodelage
Une fonctionnalité au sein d'un flux existantL'idiome que ce flux utiliseNouvelles limites
Une nouvelle classe ou un nouveau moduleLa boucle de conceptionRien
Un nouveau contexteLa boucle, puis ses limitesRien
Un nouveau système à partir de rienLa boucle, les contextes, puis la structureRien

Avant de concevoir

Avant de concevoir, énoncez la porte : une règle que le logiciel doit suivre, avec un exemple qu'elle accepte et un qu'elle rejette. Par exemple, "Un créneau peut contenir au plus un rendez-vous." Elle accepte la réservation d'un deuxième patient dans un créneau différent et rejette la réservation d'un deuxième patient dans le même créneau. Si vous pouvez écrire la règle, commencez. Si vous ne le pouvez pas, ce qui manque n'est pas de la conception, et ce pack ne peut pas le fournir.

La boucle de conception

  1. Dites ce que le logiciel doit faire dans les mots du domaine (parler le langage du domaine), et trouvez l'objet qui sait ce dont chaque comportement a besoin (assigner les responsabilités).
  2. Trouvez la limite de cohérence : ce qui doit être vrai ensemble en une seule transaction (concevoir les agrégats).
  3. Décidez où chaque règle vit : une entité, un objet-valeur ou un service du domaine (placer la logique métier).
  4. Concevez les messages auxquels chaque objet répond (encapsuler l'état et le comportement), et rendez les états impossibles à construire (rendre les états impossibles impossibles à construire).
  5. Inversez les dépendances pour que le domaine ne sache rien de la base de données ou du framework (inverser les dépendances, superposer le système).
  6. Nommez les choses dans les mots du domaine, et commentez uniquement ce que le code ne peut pas dire (nommer les classes et les méthodes, commenter ce que le code ne peut pas dire).
  7. Vérifiez le résultat par rapport aux signaux d'alarme ci-dessous (réviser la conception objet).

À quel point une règle est stricte

Chaque règle fondamentale de ce pack porte l'une des trois étiquettes suivantes, et l'étiquette indique son degré de rigueur.

  • Règle. Enfreindre cette règle est un défaut. Aucun framework ne l'excuse.
  • Défaut. Faites ceci sauf si une condition énoncée s'applique. La condition est sa propre phrase, jamais une clause subordonnée.
  • Jugement. Deux réponses sont défendables. La compétence indique ce qui fait pencher la balance.

Symptômes vers les compétences

Les symptômes pointent vers la compétence qui les traite, et ce tableau s'agrandit au fur et à mesure que les compétences arrivent.

SymptômeCompétence
Quelle classe devrait faire ceci ?Assigner les responsabilités
Cette classe fait trop de chosesAssigner les responsabilités
Un changement se répercute sur de nombreuses classesDiagnostiquer le couplage
À quel point ces deux parties sont-elles liées ?Diagnostiquer le couplage
Est-ce un objet ou juste des données ?Décider objet ou données
Notre modèle de domaine est anémiqueDécider objet ou données
D'autres code décident pour cet objetEncapsuler l'état et le comportement
Les setters permettent à cet objet d'enfreindre ses règlesEncapsuler l'état et le comportement
Cet objet peut exister à moitié construitConstruire des objets valides
Ce constructeur prend trop d'argumentsConstruire des objets valides
Chaque nouveau cas signifie modifier du code qui fonctionneEncapsuler ce qui varie
Quelle flexibilité cela devrait-il avoir ?Encapsuler ce qui varie
Est-ce une valeur ou une entité ?Modéliser les valeurs et les entités
Les chaînes brutes et les nombres portent des règles métierModéliser les valeurs et les entités
Cette classe devrait-elle étendre cette classe ou la contenir ?Choisir la composition plutôt que l'héritage
Changer une classe de base casse ses sous-classesChoisir la composition plutôt que l'héritage
Une sous-classe viole ce que promet son parentRespecter la substituabilité
Le code vérifie quel sous-type il contientRespecter la substituabilité
Le même switch sur un type revient sans cesseRemplacer les conditionnels par le polymorphisme
Sous-classes ou filtrage par motif ?Remplacer les conditionnels par le polymorphisme
Le code traverse une chaîne d'objetsLimiter ce qu'un objet sait
Cette classe ne fait que transmettre des appelsLimiter ce qu'un objet sait
Comment cette classe ou cette méthode devrait-elle être nommée ?Nommer les classes et les méthodes
Des noms comme Manager, Helper ou UtilNommer les classes et les méthodes
Les appelants dépendent de méthodes d'interface qu'ils n'utilisent jamaisConcevoir les interfaces
Interface ou classe de base abstraite ?Concevoir les interfaces
Le code du domaine dépend d'une base de données ou d'un frameworkInverser les dépendances
Où les objets sont-ils créés et câblés ensemble ?Inverser les dépendances
Les appelants savent comment une autre classe stocke ou formate les donnéesCacher l'implémentation
Une classe divulgue ses erreurs ou étapes internesCacher l'implémentation
Les drapeaux ou les champs optionnels permettent des combinaisons impossiblesRendre les états impossibles impossibles à construire
Un type admet des valeurs que le domaine n'a jamaisRendre les états impossibles impossibles à construire
Les mots du code diffèrent de ceux du personnelParler le langage du domaine
Un mot signifie des choses différentes pour deux équipesParler le langage du domaine
Quels objets doivent changer ensemble ?Concevoir les agrégats
Les sauvegardes entrent en collision ou un chargement en tire tropConcevoir les agrégats
Quels changements d'état sont autorisés ?Modéliser les cycles de vie
Un objet annulé ou fermé change à nouveauModéliser les cycles de vie
Comment les objets du domaine doivent-ils être stockés et trouvés ?Concevoir les dépôts
Le dépôt a une méthode find par écranConcevoir les dépôts
Les cas d'utilisation répètent la même vérification métierPlacer la logique métier
Service du domaine, méthode d'entité ou service applicatif ?Placer la logique métier
D'autres parties doivent réagir après qu'un changement soit enregistréPublier des événements du domaine
Un message a été envoyé pour un changement qui a été annuléPublier des événements du domaine
Où le modèle d'une équipe se termine-t-il et celui d'une autre commence-t-il ?Délimiter les contextes
Quelles parties sont essentielles, et lesquelles pouvons-nous acheter ?Délimiter les contextes
Dans quel sens les couches doivent-elles dépendre ?Superposer le système
Un écran ou une tâche ne peut pas être testé sans son frameworkSuperposer le système
Les modules dépendent les uns des autres dans un cycleOrganiser les modules
Monolithe modulaire ou services séparés ?Organiser les modules
Un changement dans notre API casse les applications qui l'appellentFranchir les frontières système
Comment versionner cette API ou ce message ?Franchir les frontières système
L'outil de mapping façonne nos classes du domaineMaîtriser la persistance
Une liste exécute une requête par ligneMaîtriser la persistance
Les écrans ont besoin de données façonnées différemment du modèleSéparer les lectures des écritures
Modèle de lecture, projection ou event sourcing ?Séparer les lectures des écritures
MVC, MVP ou MVVM pour cet écran ?Séparer la présentation du domaine
Un écran édite directement des objets du domaineSéparer la présentation du domaine
Quel patron de conception correspond à ce problème ?Choisir un patron
Un patron a été ajouté avant son problèmeChoisir un patron
Ces classes de patron pourraient être une fonctionPatrons que le langage fournit
Visiteur, ou un ensemble fermé avec filtrage ?Patrons que le langage fournit
Une méthode retourne null quand elle ne trouve rienConcevoir le comportement en cas d'échec
Les refus reviennent sous forme de codes que les appelants ignorentConcevoir le comportement en cas d'échec
Les threads partagent un objet et perdent ou mélangent ses modificationsGérer l'état partagé
Un verrou ou un propriétaire unique pour cet état ?Gérer l'état partagé
Un appel à un autre système se bloque ou échoue à mi-cheminRendre le travail fiable
Une nouvelle tentative a effectué le travail deux foisRendre le travail fiable
Nous ne pouvons pas expliquer un incident à partir de nos enregistrementsConcevoir ce qu'il faut enregistrer
Que devons-nous journaliser, compter ou auditer ?Concevoir ce qu'il faut enregistrer
Un examen a trouvé une classe god ou un lava flowReconnaître les antipatrons
Quel antipatron devrions-nous corriger en premier ?Reconnaître les antipatrons
Les tests cassent bien que le comportement n'ait pas changéTester le code orienté objet
Mock, stub ou faux pour ce collaborateur ?Tester le code orienté objet
Les tests dépendent de l'heure ou de valeurs aléatoiresConcevoir pour la testabilité
Le code est rendu public uniquement pour que les tests puissent l'atteindreConcevoir pour la testabilité
Comment restructurer ce code en toute sécurité ?Refactoriser vers la conception objet
Un refactoring est devenu trop gros pour être terminéRefactoriser vers la conception objet
Nous devons modifier du code qui n'a pas de testsTravailler avec du code legacy
Remplacer un ancien système pièce par pièceTravailler avec du code legacy
Que doit vérifier cette revue ?Réviser la conception objet
Quels résultats de revue bloquent une fusion ?Réviser la conception objet
Personne ne se souvient pourquoi le code est façonné ainsiDocumenter les décisions de conception
Que devrions-nous dessiner, et à quel niveau ?Documenter les décisions de conception
Les commentaires répètent le code ou le contredisentCommenter ce que le code ne peut pas dire
Où expliquer pourquoi ce code semble étrange ?Commenter ce que le code ne peut pas dire
Un hook ou un marqueur de framework contient une règle métierTravailler au sein d'un framework
Jusqu'où devrions-nous suivre le framework ?Travailler au sein d'un framework
Un calcul sauvegarde, envoie ou modifie également ses entréesAppliquer des techniques fonctionnelles
Quelles techniques fonctionnelles conviennent au code objet ?Appliquer des techniques fonctionnelles

Compétences linguistiques

Une compétence linguistique conserve les règles fondamentales dans un langage et ne les remplace jamais. Une compétence linguistique de base est destinée au code sans framework.

  • oo-java, de object-oriented-design-java : enregistrements, types scellés, equals et hashCode, exceptions vérifiées, Optional, et classes fermées à l'extension.
  • oo-kotlin, de object-oriented-design-kotlin : classes de données, types scellés, types nullables, délégation avec by, et fonctions d'extension.
  • oo-typescript, de object-oriented-design-typescript : identifiants marqués, état #private, classes abstraites, décorateurs, unions discriminées, et racine de composition.
  • oo-javascript, de object-oriented-design-javascript : classes, fermetures, délégation par mixins, modules ES, et fonctions comme objets de première classe.

Licence

Cette compétence est fournie dans l'espoir qu'elle sera utile, mais SANS AUCUNE GARANTIE, implicite ou explicite. Consultez le fichier LICENSE dans le dépôt d'origine pour plus de détails.

Skills associés