Code propre en C# : de .NET, CLR et BCL à la Clean Architecture
Pourquoi une petite modification peut-elle prendre toute une journée ? Comprendre .NET, écrire un C# lisible et définir les responsabilités : un parcours concret vers la Clean Architecture, avec des exemples du quotidien et une méthode pour améliorer l’existant sans tout réécrire.
L’article complet est disponible ci-dessous. Activez JavaScript pour les quiz et les simulations.
Dossier spécial · l’atelier du développeur
Du code que l’on retrouve l’esprit clair.
Lundi, 9 h 12. Le café est encore brûlant. Un message arrive sur le chat : « On change les règles d’annulation des réservations. C’est une petite modification, non ? » Vous ouvrez le projet. La même règle se trouve dans le contrôleur, dans une tâche de fond et dans l’administration. Elle est légèrement différente partout.
C’est dans ces moments que la qualité du code se révèle. Il faut retrouver la règle, comprendre sa raison et modifier le comportement sans casser le reste du système. Parcourons ce chemin ensemble : de ce que fait réellement .NET à un C# lisible, puis aux frontières qui facilitent l’évolution d’une application.
Auteur : ArcCloud Studio · informations sur les versions vérifiées le 8 octobre 2026. L’atelier de vélos et les scènes d’équipe sont des exemples pédagogiques, pas un projet client.
Choisissez votre point de départ
01 / Les fondations
Qu’est-ce que .NET et où se situe C# ?
Lors d’un premier projet, on confond facilement C#, .NET, Visual Studio et ASP.NET Core. En équipe, les distinguer devient vite utile. Quand une application refuse de démarrer sur un serveur, il faut savoir si le runtime manque, si le système choisi est inadapté ou si le mauvais fichier a été publié.
C# est un langage ; .NET est une plateforme de création et d’exécution d’applications. Le langage exprime les règles. La plateforme fournit un environnement d’exécution, des bibliothèques et des outils. ASP.NET Core sert notamment à construire des applications HTTP et des API. Visual Studio, Rider et VS Code sont des outils de travail ; le choix de l’éditeur ne change pas les règles métier.
C#
Vous décrivez un comportement : réserver, annuler un rendez-vous, calculer un prix. Le compilateur vérifie la syntaxe et les types.
Runtime / CLR
L’environnement exécute le code managé et fournit les services nécessaires au programme.
SDK
Vous construisez, exécutez et publiez l’application. Le SDK contient notamment la CLI, le compilateur et le runtime.
Sur le poste du développeur, on installe généralement le SDK. Sur le serveur, l’exécution dépend du mode de publication : l’application peut utiliser un runtime installé ou embarquer le sien. Dire « j’ai .NET » manque donc parfois de précision. Mieux vaut identifier la version du SDK, le framework cible et le modèle de déploiement.
Terminal · trois questions à poser à l’environnement
dotnet --list-sdks
dotnet --list-runtimes
dotnet --infoLa première commande indique avec quoi vous pouvez construire. La deuxième liste les runtimes installés. La troisième rassemble des informations de diagnostic. C’est un bon départ quand un projet fonctionne chez une personne et échoue chez une autre avant même la première ligne de notre code.
Documentation : composants de la plateforme .NET et le SDK et son rôle.
CLR et BCL : le moteur et les outils du quotidien
Le CLR, Common Language Runtime, est l’environnement d’exécution du code managé. Dans le .NET moderne sur un serveur classique, on rencontre l’implémentation CoreCLR. Le runtime gère notamment l’exécution, les exceptions, le système de types et la mémoire automatique. Les détails varient selon la plateforme et le mode de publication.
La BCL, Base Class Library, fournit les types et opérations de base. Lorsque vous utilisez string, List<T>, DateTimeOffset ou manipulez des fichiers avec System.IO, vous utilisez ce socle. Votre classe Booking décrit votre métier. La BCL fournit les briques qui évitent de réécrire le traitement du texte, des collections et des dates.
Différence pratique : « impossible de trouver le runtime approprié » n’est pas le même problème qu’une comparaison de dates erronée dans une réservation. Le premier concerne le démarrage, le second une règle que nous avons écrite. Un bon diagnostic commence par identifier le niveau du défaut.
Que se passe-t-il quand on clique sur « Exécuter » ?
Dans le modèle JIT habituel, le compilateur C# produit du code intermédiaire IL et des métadonnées. Pendant l’exécution, le JIT traduit le code nécessaire en instructions adaptées au processeur. Ce schéma est simplifié ; les optimisations du runtime sont plus riches qu’un seul dessin.
Et Native AOT ?
Native AOT prépare le code natif lors de la publication et n’utilise donc pas de JIT au démarrage. Cela peut réduire le temps de démarrage et la mémoire consommée. Il faut toutefois vérifier la compatibilité des bibliothèques, la réflexion et les limites du chargement dynamique. Le résultat dépend du système et de l’architecture choisis. AOT utilise toujours des mécanismes du runtime, dont le GC. Fondez la décision sur des mesures de l’application concernée.
Le Garbage Collector récupère la mémoire. Les ressources restent notre responsabilité.
Le GC peut récupérer la mémoire des objets qui ne sont plus accessibles depuis les racines de l’application. Si un grand dictionnaire ou un gestionnaire d’événements conserve une référence, l’objet peut rester bien plus longtemps que prévu. La gestion automatique de la mémoire ne dispense pas de réfléchir à la durée de vie des données.
Les handles et ressources externes sont un autre sujet. Un fichier doit être fermé après usage et un objet libérable doit respecter son contrat. Les constructions using et await using expriment cette intention dans le code. C’est aussi de la lisibilité : on voit où la ressource est utile et où sa vie se termine.
Pour approfondir : glossaire .NET, exécution du code managé, Native AOT et bases du GC.
02 / Les versions sans devinettes
.NET Framework, .NET Core et .NET : pourquoi tous ces noms ?
Vous reprenez une application. Dans le dépôt, vous voyez net48, dans un autre projet net8.0, tandis qu’une bibliothèque partagée cible netstandard2.0. Ces notations décrivent différentes cibles de compilation. La ressemblance des noms ne signifie pas que tous les projets peuvent être déplacés sur le même serveur sans préparation.
Le tableau défile horizontalement →
| Famille | Signification | À vérifier dans le projet |
|---|---|---|
| .NET Framework | Famille liée à Windows. La version la plus récente est 4.8.1 ; son support dépend de celui du système d’exploitation. | Dépendances à Windows, à l’ancien ASP.NET, aux bibliothèques tierces et au mode de déploiement. |
| .NET Core | Lignée historique 1.0–3.1, développée comme plateforme multiplateforme. | Plan de mise à niveau. Ces versions ne sont plus prises en charge. |
| .NET 5 et versions suivantes | Suite de .NET Core sous un nom raccourci. Plateforme moderne pour plusieurs systèmes et types d’applications. | Version cible, support, packages et exigences de l’environnement. |
| .NET Standard | Spécification d’un ensemble commun d’API pour les bibliothèques. Ce n’est pas un runtime applicatif. | Les consommateurs de la bibliothèque. Framework ne prend pas en charge .NET Standard 2.1. |
Il n’y a pas eu de « .NET Core 4 ». .NET 5 a succédé à .NET Core 3.1. ASP.NET Core et Entity Framework Core ont conservé « Core », que l’on retrouve donc dans les nouveaux projets. La version du langage C# est une autre notion : un projet peut employer une version précise du langage tout en ciblant un framework donné.
Que choisir aujourd’hui ?
Au 8 octobre 2026, .NET 10 est une version LTS prise en charge jusqu’au 14 novembre 2028. .NET 8 LTS et .NET 9 STS le sont jusqu’au 10 novembre 2026. Pour une nouvelle application, évaluez .NET 10 LTS avec la compatibilité des bibliothèques et de l’environnement. Pour un projet existant en 8 ou 9, la priorité devient un plan concret de mise à niveau et de vérification du comportement.
À cette date, .NET 11 est annoncé pour novembre 2026. Cet article ne considère pas une préversion comme base de production par défaut. Si vous le lisez plus tard, consultez le tableau Microsoft actuel ; les dates décrivent le moment de rédaction.
Un bon plan de migration commence par un inventaire. Recensez les packages, intégrations, dépendances Windows, méthodes de build et scénarios critiques. Exécutez ensuite les tests et prévoyez le retour à la version précédente. Remplacer simplement net48 par net10.0 dans le projet ne répond pas à ces questions.
Si vous maintenez une bibliothèque partagée avec une application .NET Framework, netstandard2.0 peut rester justifié. Si elle sert uniquement au .NET moderne, une cible récente permet d’en utiliser les API. Le choix dépend des consommateurs, pas seulement de l’âge du nom.
Sources sur les versions : politique officielle de support .NET, support de .NET Framework et .NET Standard.
Sur le bureau du développeur / lundi, 10 h 05
« J’ai trouvé trois endroits. Il faut maintenant déterminer lequel dit vrai. »
L’équipe reprend les règles d’annulation. Une méthode compare les heures, une autre les dates calendaires, la troisième ne regarde que le statut. Comprendre le comportement actuel prend plus de temps qu’écrire une nouvelle condition. C’est ici que commence la discussion sur le code propre.
03 / Une lisibilité qui facilite le changement
Que signifie réellement « code propre » ?
Regardez le code avec les yeux de la personne qui corrigera un bug dans six mois. Ce sera peut-être un nouveau collègue. Peut-être vous, après plusieurs projets et une semaine de vacances. Retrouvera-t-elle rapidement la règle ? Comprendra-t-elle le nombre 24 ? Pourra-t-elle vérifier la correction sans parcourir manuellement toute l’application ?
La lisibilité se construit par de petites décisions. Le nom CanCancel en dit plus que Check. Le paramètre minimumNotice explique une valeur auparavant réduite à un nombre nu. Une méthode courte est utile lorsqu’elle accomplit une tâche cohérente. Éparpiller quelques lignes simples entre une douzaine de méthodes peut compliquer la lecture.
Dans notre exemple, le propriétaire de l’atelier de vélos autorise l’annulation jusqu’à 24 heures avant le rendez-vous. Précisons les limites : exactement 24 heures, c’est autorisé ; 24 heures moins un tick, non. Annuler à nouveau une réservation déjà annulée doit produire un résultat explicite sans répéter les effets secondaires.
Avant · il faut deviner le sens
if (b.S == 0 &&
(b.T - DateTime.Now).TotalHours > 24)
{
b.S = 1;
}Écrivez la règle en une phrase
« Une réservation confirmée peut être annulée au moins 24 heures avant le rendez-vous. »
Définissez les statuts, la limite temporelle et le comportement en cas de répétition. Choisissez ensuite les noms et les types.
Ce petit extrait cache plusieurs décisions. Que signifie le statut zéro ? Pourquoi l’opérateur est-il plus strict que la règle convenue ? S’agit-il de l’heure locale ? D’où viendra « maintenant » dans le test ? Corriger l’indentation ne résout aucune de ces questions.
Un commentaire doit conserver la raison d’une décision
Expliquez pourquoi l’atelier a besoin de 24 heures : libérer le poste de travail et prévenir le mécanicien, par exemple. Ce commentaire aidera lors d’une évolution des règles. « Passe le statut à annulé » au-dessus de la méthode Cancel ne fait généralement que répéter le code.
Il en va de même pour la duplication. Une règle métier doit avoir une source identifiable unique. Mais deux fragments similaires servant des processus distincts ne doivent pas forcément être fusionnés. Facturer une intervention individuelle et gérer un contrat de flotte peuvent se ressembler aujourd’hui, puis évoluer selon des règles différentes. Un « processus universel » abstrait masque souvent cette distinction.
SOLID aide-t-il encore ?
Oui, si ces principes servent à poser des questions. SRP montre qu’une règle d’annulation et un fournisseur d’e-mails ont des responsables différents. ISP encourage des contrats réduits aux besoins d’un consommateur. DIP sépare le cas d’utilisation des détails de stockage. LSP rappelle qu’une implémentation doit tenir les promesses du contrat. OCP invite à chercher des points d’extension là où les changements sont fréquents. Chaque couche doit toutefois résoudre un problème réel et son coût doit être compris par l’équipe.
La règle d’abord. Puis un moyen simple de l’utiliser.
Avant la base, le contrôleur et les e-mails, nous pouvons tester la décision seule. L’extrait suivant isole la règle temporelle. Le projet téléchargeable plus bas la complète avec l’état de réservation et le cas d’utilisation.
C# · règle explicite et temps explicite
public static bool HasEnoughNotice(
DateTimeOffset startsAt,
DateTimeOffset now,
TimeSpan minimumNotice)
{
if (minimumNotice < TimeSpan.Zero)
throw new ArgumentOutOfRangeException(
nameof(minimumNotice));
return startsAt - now >= minimumNotice;
}
var allowed = HasEnoughNotice(
startsAt,
now,
TimeSpan.FromHours(24));Nous passons le temps comme valeur : le test n’a pas à attendre demain ni à modifier l’horloge du poste. DateTimeOffset décrit un instant avec son décalage UTC ; la comparaison en tient compte. Ce n’est toutefois pas un modèle complet de fuseau horaire. Pour des rendez-vous récurrents « à 9 h à Varsovie », il faut aussi les règles de ce fuseau, dont les changements d’heure.
Nous avons défini la règle comme 24 heures effectivement restantes. Si les conditions disaient « avant la fin du jour ouvré précédent », le modèle serait différent. Jours fériés, fuseau et horaires de travail feraient partie du problème. Une bonne implémentation commence par la bonne question au métier.
« Maintenant » ne doit pas venir du formulaire client. L’application choisit une source de temps fiable. En .NET, on peut utiliser TimeProvideret contrôler sa valeur dans les tests. L’utilisateur fournit l’identifiant de réservation ; le serveur fixe le temps et vérifie les droits.
Cette méthode exige-t-elle immédiatement sa propre interface ? Pas forcément. Une fonction pure sur des valeurs est facile à exécuter et à comprendre. Une interface est surtout utile face à une dépendance à remplacer ou masquer : stockage, horloge, service externe. Trop de contrats ont aussi un coût de lecture.
Pour contrôler le temps : TimeProvider dans la documentation Microsoft.
04 / Les frontières des responsabilités
La Clean Architecture en C#, en pratique
L’application grandit. Arrivent l’administration, le calendrier, les notifications et les paiements. Nous voulons comprendre l’annulation sans lire la configuration des e-mails. La Clean Architecture organise les dépendances pour que les détails techniques ne prennent pas le contrôle du métier.
Le principe essentiel concerne le sens des dépendances dans le code : elles vont vers l’intérieur, vers les règles et cas d’utilisation. Le domaine n’a pas à connaître le contrôleur HTTP ou Entity Framework. Le cas d’utilisation peut définir son contrat de stockage, dont l’infrastructure fournit l’implémentation.
API / interface et Infrastructure
HTTP, accès aux données, e-mail, services externes. Les adaptateurs ajustent le monde extérieur aux besoins de l’application.
Application
« Annuler une réservation » : charger, interroger le domaine, tenter d’enregistrer, renvoyer le résultat.
Domain
Statut, date du rendez-vous et préavis requis. Sans dépendance à HTTP ou à une base précise.
Le schéma représente les dépendances du code. À l’exécution, un appel peut aller d’Application à un adaptateur Infrastructure via une interface.
Ce détail suscite souvent la confusion. « L’application doit pourtant appeler la base ! » Oui, mais elle n’a pas à connaître sa classe concrète. L’interface est le contrat ; l’adaptateur le réalise. Le code de démarrage, parfois appelé composition root, relie les composants par injection de dépendances.
Dans un petit projet, les frontières peuvent d’abord être des modules et dossiers. Des projets séparés permettent ensuite d’imposer les références à la compilation. L’important est que le répertoire Domain n’importe pas discrètement le contexte de base et que le nom Application ne devienne pas un nouveau fourre-tout.
Exemple de découpage · dépendances des projets
Domain → bibliothèques de base .NET
Application → Domain
Infrastructure → Application, Domain
Demo / API → Application, Infrastructure
+ enregistrement des dépendancesL’application peut rester un seul processus déployable. Un monolithe modulaire offre souvent un contrôle suffisant des frontières sans communication réseau supplémentaire. Extraire un microservice devient pertinent pour des raisons concrètes : responsabilité d’équipe, déploiement indépendant ou contraintes opérationnelles différentes.
Sens des dépendances et exemples de découpage : architectures web dans la documentation Microsoft.
05 / Un seul cas d’utilisation
Suivons l’annulation d’une réservation de bout en bout
Le client choisit une réservation et clique sur « Annuler ». Dans l’application complète, la couche d’entrée vérifie d’abord son identité et ses droits sur cette réservation. Un identifiant valide ne constitue pas une autorisation. Elle transmet ensuite la demande au cas d’utilisation qui pilote l’opération.
- Entrée.L’API lit l’identifiant, valide la requête et vérifie l’autorisation sur la ressource.
- Lecture.Application charge la réservation via le contrat du dépôt. L’absence d’enregistrement est un résultat explicite.
- Décision.Le domaine vérifie l’état et le temps. La règle des 24 heures vit ici.
- Enregistrement.L’adaptateur tente de persister le nouvel état avec un contrôle de version. Un conflit n’est pas une réussite silencieuse.
- Réponse.L’API traduit le résultat dans le contrat HTTP convenu. L’interface explique ce qui s’est passé.
C’est le bon moment pour nommer les résultats de l’opération. Cancelled, AlreadyCancelled, TooLate, NotFound et Conflict expriment clairement la situation. Un refus métier attendu n’a pas forcément à être une exception. Une panne inattendue de connexion à la base demande un traitement distinct et ne doit pas prétendre que la réservation est simplement introuvable.
Voir un extrait du domaine du projet téléchargeable
Domain/Booking.cs · méthode de la classe Booking
public BookingCancellation Cancel(
DateTimeOffset now,
CancellationPolicy policy)
{
if (Status == BookingStatus.Cancelled)
return new(this,
CancellationDecision.AlreadyCancelled);
if (StartsAt <= now)
return new(this,
CancellationDecision.VisitStarted);
if (StartsAt - now < policy.MinimumNotice)
return new(this,
CancellationDecision.TooLate);
return new(
this with { Status = BookingStatus.Cancelled },
CancellationDecision.Cancelled);
}Dans l’exemple, Booking est un record. Une décision positive crée une nouvelle valeur au statut annulé. Les autres décisions conservent l’objet précédent. Les types complets, constructeurs et contrats figurent dans l’archive.
Qu’apporte le contrat du dépôt ?
Dans l’atelier, le cas d’utilisation a besoin de deux opérations : trouver une réservation et tenter d’enregistrer son nouvel état avec la version attendue. Ce petit contrat est lisible. Nous ne construisons pas un dépôt universel pour tous les types, avec des dizaines de méthodes inutilisées ici.
Une vraie application peut adopter un autre compromis, comme l’utilisation directe d’EF Core dans un module précis. Il faut alors assumer cette dépendance et son mode de test. La Clean Architecture n’exige ni bibliothèque particulière, ni médiateur, ni interface pour chaque classe. Elle aide l’équipe à préserver des frontières compréhensibles.
Et si deux personnes cliquent en même temps ?
La lecture peut n’être actuelle qu’un instant. Entre chargement et enregistrement, quelqu’un peut modifier la réservation. Nous transmettons donc la version lue à la tentative d’écriture. L’adaptateur doit détecter qu’elle n’est plus valable. Le code applicatif décide s’il relit ou renvoie un conflit.
Dans un adaptateur de production, le mécanisme d’écriture doit vérifier la version atomiquement. Une requête séparée « la version correspond-elle ? » ne protège pas la mise à jour suivante. L’exemple en mémoire montre le contrat, mais ne remplace pas les tests de transaction et de concurrence sur le véritable moteur de base.
Sur le bureau du développeur / vendredi, 16 h 40
Réservation annulée. E-mail non reçu. Que doit voir le client ?
Le fournisseur d’e-mails a cessé de répondre après l’enregistrement en base. Le bouton attend toujours. Le client actualise et réessaie. C’est là que les frontières transactionnelles et les reprises comptent davantage que l’élégance du diagramme.
Le beau code doit affronter le monde réel
Enregistrer une réservation et envoyer un message via un prestataire ne forment généralement pas une transaction commune. Les considérer comme indivisibles sans plan de panne peut afficher une erreur alors que la modification est enregistrée. L’utilisateur ignore alors s’il doit réessayer.
Une solution est l’outbox : avec le changement d’état, la même transaction enregistre l’intention d’envoyer une notification. Un processus distinct tente la livraison et suit son avancement. Il reste pourtant à traiter reprises, doublons, identifiant d’opération, limite de tentatives et tâches bloquées. Appeler une table « Outbox » ne garantit pas une livraison unique.
Dans cet atelier, l’exemple s’arrête volontairement avant les e-mails. Nous voulons comprendre une frontière, puis élargir explicitement le périmètre. Le code téléchargeable ne contient ni authentification de production, ni contrôle du propriétaire, ni base SQL, ni paiements. Ces éléments doivent être conçus et testés dans le contexte du service.
Async, exceptions et journaux influencent aussi la lisibilité
Pour les entrées-sorties, transmettez systématiquement CancellationToken et utilisez des API asynchrones. Le mot async n’accélère pas à lui seul les calculs et ne crée pas automatiquement un thread. Il décrit la coopération du code pendant l’attente de fin d’une opération.
La gestion des erreurs demande la même discipline. Un catch vide peut faire taire une alarme, mais laisse l’utilisateur dans l’incertitude. Un journal doit aider à reconstruire le parcours : identifiant d’opération, étape et résultat. Il n’a pas besoin du mot de passe, du jeton ou du formulaire complet. Concevez le diagnostic avec le cas d’utilisation.
Contexte technique : défaillances partielles et résilience des applications.
06 / Vérifier avant de déclarer terminé
Des tests qui répondent aux questions de l’équipe
Le plus simple est de tester le cas heureux. Dans notre atelier, une réservation pour la semaine suivante peut être annulée. C’est un bon début, mais les malentendus se cachent surtout à la limite de la règle et lors des répétitions.
Le tableau défile horizontalement →
| Situation | Comportement attendu | Ce que nous vérifions |
|---|---|---|
| Exactement 24 heures avant le rendez-vous | Annulation autorisée | La limite définie par les conditions |
| 24 heures moins un tick | Refus : trop tard | Précision de la comparaison sans arrondi |
| Même instant, autre décalage UTC | Même résultat | Comparer des instants, pas l’affichage de l’horloge |
| Réservation déjà annulée | Résultat explicite de la répétition | Aucune nouvelle modification d’état |
| Enregistrement modifié après la lecture | Conflit détecté | Contrat de contrôle de version |
| Annulation réussie puis nouvelle lecture | État annulé visible | Persistance réelle dans l’adaptateur utilisé |
Le test du domaine s’exécute sans serveur. Celui du cas d’utilisation vérifie la coopération entre règle, horloge et contrat de stockage. Le test d’intégration de l’adaptateur doit montrer si requêtes, transactions et contraintes fonctionnent sur le moteur retenu. Enfin, le test du parcours utilisateur vérifie l’affichage du succès, du refus et de l’erreur.
Ne confondez pas ces preuves. Un test vert sur une collection en mémoire ne valide pas une requête SQL. Un moteur différent peut traiter autrement comparaisons, types ou transactions. Et 100 % de couverture des lignes ne prouvent pas que les principaux risques sont testés.
Atelier à télécharger · C#
Atelier de vélos : un petit projet, le parcours complet d’une décision
L’archive contient Domain, Application, un adaptateur en mémoire, une démonstration et des scénarios de contrôle. Sans paquet NuGet supplémentaire. Suivez les dépendances, modifiez les règles et observez quelles attentes cessent d’être valables.
Télécharger le projet C# et la notice ZIP ↓Framework cible du projet : .NET 10. Le README décrit les prérequis, le lancement, les vérifications réalisées et les limites de la démonstration.
Un exercice pour une demi-heure au calme
Le propriétaire veut réduire le préavis de 24 à 12 heures. Avant de modifier le code, écrivez les cas exactement à 12 heures et juste en dessous. Modifiez ensuite la politique et exécutez les scénarios. Devez-vous changer simultanément contrôleur, adaptateur et modèle ? Si oui, cherchez où la règle a débordé de sa responsabilité.
La seconde partie est plus difficile : les nouvelles conditions ne doivent concerner que les réservations créées après une date donnée. Modifier globalement une valeur peut violer les conditions déjà acceptées. La réservation doit peut-être mémoriser la version de sa politique. Voilà pourquoi il faut comprendre le sens d’un changement avant de se réjouir de sa simplicité dans le code.
Pour choisir les preuves : stratégie de test des applications utilisant EF Core.
Pause pratique
Trois décisions au bureau
Choisissez une réponse et lisez l’explication. Vous pouvez réessayer. L’exercice fonctionne localement dans le navigateur ; ce n’est ni une évaluation de compétences ni un certificat.
1. Où placer la règle des 24 heures ?
Uniquement dans le bouton et le formulaire Angular.
Dans le domaine, appelé par le cas d’utilisation.
Choisissez une réponse pour voir l’explication.
2. Vous souhaitez détecter un défaut transactionnel dans l’adaptateur SQL.
J’ajoute un test d’intégration sur le moteur de base approprié.
Je remplace la base par List<Booking> et considère le sujet réglé.
Choisissez une réponse pour voir l’explication.
3. Une petite application possède deux formulaires simples et une seule équipe.
Je la répartis immédiatement entre plusieurs microservices.
Je commence par des modules simples et recherche les frontières utiles.
Choisissez une réponse pour voir l’explication.
Recommencer
Répondez aux trois questions. Chaque décision est accompagnée d’une explication.
Réponses et explications en texte
1. La règle appartient au domaine appelé par le cas d’utilisation. La validation du formulaire facilite l’usage, mais ne protège pas le serveur. 2. Le comportement transactionnel exige un test de l’adaptateur sur le bon moteur dans une base de test distincte. 3. Des modules simples peuvent suffire ; les frontières évoluent avec les besoins. Ces réponses restent accessibles sans boutons interactifs.
Sur le bureau du développeur / premier mercredi dans l’équipe
« J’ai trouvé CancelBooking. Je vois la règle et le test de sa limite. »
La nouvelle collègue ne connaît pas encore l’histoire du projet. Pourtant, elle sait localiser la modification et en expliquer les conséquences. C’est un bon signe de qualité : le fonctionnement est documenté dans le code, les tests et quelques notes, plutôt que dans la seule mémoire d’une personne.
07 / Un projet qui rapporte déjà
Comment refactoriser sans tout réécrire ?
Dans une application existante, remettre calmement de l’ordre dans un processus souvent modifié apporte fréquemment le plus de valeur. Choisissez une zone où les bugs reviennent, où un test est difficile à ajouter ou où une demande simple touche plusieurs modules. Au lieu de bouleverser tout le système, tracez une opération : entrée, règle, enregistrement et réponse.
Commencez par décrire le comportement actuel. Les tests de caractérisation le capturent même si la documentation est incomplète. Tous les détails hérités ne sont pas intentionnels : discutez les écarts. La refactorisation améliore la structure en préservant le comportement convenu. Séparez les changements métier pour que le destinataire sache ce qu’il approuve.
- Comprenez le processus.Entrées, données, règles, intégrations et effets secondaires. Identifiez le responsable de la décision métier.
- Protégez le comportement actuel.Ajoutez des tests des scénarios importants et un moyen de reproduire le problème signalé.
- Isolez une responsabilité.Déplacez une règle ou un adaptateur par petit pas. Gardez l’application fonctionnelle après chaque modification.
- Vérifiez les limites.Refus, donnée absente, conflit, répétition et panne d’une dépendance. Adaptez les tests au risque.
- Déployez et observez.Préservez le retour arrière et les informations permettant d’évaluer le comportement après déploiement.
La code review comme discussion sur le prochain changement
Demandez en revue : « Et si l’enregistrement échoue ? », « Cette méthode peut-elle être appelée deux fois ? », « Quel test prouve cette limite ? ». Ces questions aident l’auteur à préciser la solution. Discuter seulement des parenthèses est moins utile ; les outils peuvent gérer les règles mécaniques de formatage.
Une bonne description résume le problème, le nouveau comportement et la vérification en quelques phrases. Pour une décision difficile, une brève note d’architecture conserve le choix, sa raison et le moment de le réexaminer. Le collègue suivant n’aura pas à reconstruire des semaines de discussion dans le chat.
Une petite liste pour la prochaine pull request
- Les noms expriment-ils les concepts métier ?
- La règle possède-t-elle une source identifiable unique ?
- Peut-on contrôler le temps et les dépendances dans les tests ?
- Le refus, l’erreur technique et le conflit ont-ils des résultats clairs ?
- Avons-nous vérifié l’accès à la ressource, pas seulement la connexion ?
- Savons-nous déployer et annuler la modification sans danger ?
- Avons-nous décrit les limites des tests et les risques restants ?
Quand une solution plus simple suffit-elle ?
Toutes les applications n’exigent pas un modèle de domaine élaboré. Un tableau de bord avec quelques opérations CRUD peut rester lisible avec peu de couches. Des cas d’utilisation bien nommés, une validation cohérente et des tests des parcours critiques sont souvent un bon départ.
Des frontières plus fortes deviennent précieuses lorsque grandissent les règles, intégrations, canaux d’entrée ou équipes. Comprendre ce qui peut changer coûte alors parfois plus que des contrats supplémentaires. L’architecture doit répondre à cette situation précise.
Laissez aussi de la place à une évolution progressive. Inutile de prévoir tous les futurs prestataires de paiement. Vous pouvez cependant séparer votre processus de facturation des détails du SDK actuel. Lors d’un changement de fournisseur, vous saurez où commencer. Il faudra toujours vérifier les différences de contrats, données et comportements : une interface ne les efface pas.
Si une règle change demain, l’équipe saura-t-elle où la modifier et comment prouver que le reste fonctionne encore ?
De la lecture à votre projet
Chaque modification de votre système entraîne-t-elle d’autres corrections ?
Montrez-nous un processus concret : connexion, réservation, commande, paiement ou intégration. Chez ArcCloud Studio, nous travaillons avec C#, .NET, Angular, AWS et Azure. Nous pouvons examiner les responsabilités mêlées, les problèmes qui touchent les utilisateurs et les premières corrections utiles.
Définir ce qu’il faut vérifier
Objectif métier, symptômes, éléments disponibles et périmètre convenu. Les accès et la confidentialité se définissent avant le partage d’informations sensibles.
Décrire les actions concrètes
Problèmes, impacts, priorités, corrections proposées et critères de recette. Périmètre de réalisation, prix et délai sont convenus séparément.
Vérifier l’effet de la modification
Après accord, nous pouvons appliquer les corrections, effectuer les tests convenus et transmettre la documentation utile à l’équipe.
Une revue d’architecture et de code demande les éléments appropriés et un périmètre défini ensemble. La mesure automatique d’une URL publique ne remplace pas ce travail.
Un premier message peut se limiter au problème, aux technologies et au résultat attendu. N’envoyez ni mots de passe ni clés d’accès dans le formulaire public.
Pour aller un peu plus loin
Revenez au diagramme et suivez un processus de votre projet. Lisez ensuite notre article sur les décisions d’architecture et la documentation de leurs raisons ou l’atelier sur les files, les reprises et la résilience des intégrations.
Les sources Microsoft sont liées dans les chapitres concernés. Les histoires, le parcours pédagogique et le code ont été préparés pour cet article. La couverture est une illustration conceptuelle réalisée avec l’aide de l’IA ; elle ne représente pas un système client.
Si vous savez maintenant distinguer langage, runtime et bibliothèques, identifier le responsable d’une règle et choisir un test selon le risque, vous avez une bonne base pour votre prochaine modification. Commencez par un processus. Observez ce qui devient plus facile à comprendre.