L’auteur partage sa réflexion sur la conception d’un outil logiciel personnel simple, un logiciel de bureau pour usage exclusif, rejetant les solutions SaaS ou cloud. Il opte pour une application macOS développée en Flutter, avec une base de données SQLite locale, évitant ainsi toute dépendance à internet ou infrastructure serveur. La simplicité prime, avec une gestion automatique des données pour éviter toute maintenance utilisateur.
Pour étendre l’application à mobile (Android et iOS) sans dupliquer le code, il sépare la logique métier des données utilisateur, comparant cela à partager une recette de gâteau plutôt que les ingrédients. Flutter permet de compiler une seule base de code Dart en applications natives pour chaque plateforme, sans recourir à une architecture client-serveur coûteuse ou complexe.
L’article explique comment appliquer correctement le pattern MVC en Symfony pour séparer la logique métier des contrôleurs et des vues, afin d’améliorer la maintenabilité du code. Il souligne que le Model ne se résume pas à une seule classe, mais se répartit entre entités, repositories et services, chacun ayant un rôle précis : les entités définissent la structure des données, les repositories gèrent les requêtes à la base de données, et les services encapsulent la logique métier.
L’auteur illustre cette séparation avec un exemple concret de contrôleur Symfony qui délègue la récupération d’un article à un repository et affiche les données via une vue Twig. Il met en garde contre l’illusion d’un MVC "propre" en rappelant que la logique métier ne doit pas être dispersée dans les contrôleurs ou les templates, mais centralisée dans des services dédiés.
Enfin, le billet insiste sur l’importance de cette discipline pour éviter un code désorganisé, tout en reconnaissant que la séparation idéale est souvent compromise dans la pratique. Il conclut que le MVC est davantage un vocabulaire commun qu’un plan rigide, et que sa mise en œuvre repose sur une réflexion constante sur l’architecture.
L’article explore l’application des principes du Domain-Driven Design (DDD) pour structurer une architecture front-end plus claire et alignée sur les besoins métiers. L’auteur, Othniel Visky, partage son expérience sur un projet de refonte d’une application de calcul de charge explosive, où le DDD a permis de créer une base de code plus compréhensible et évolutive. Le DDD résout notamment le problème de l’organisation chaotique des composants front-end, souvent classés de manière arbitraire (comme dans Atomic Design), en les regroupant par domaine métier, reflétant ainsi leur fonction réelle.
Le cœur du DDD repose sur deux concepts clés : le modèle (représentation des règles métiers) et le langage ubiquitaire (vocabulaire commun entre développeurs et experts métiers). Ce dernier évite les malentendus en standardisant la terminologie, facilitant la collaboration. Par exemple, dans le projet cité, le DDD a permis de structurer le code autour des concepts spécifiques au calcul de charge explosive, rendant les discussions avec les experts métiers plus fluides et les implémentations plus précises.
Enfin, l’auteur souligne que le DDD ne se limite pas à l’architecture technique : il transforme la façon dont les équipes conçoivent et maintiennent un produit. En adoptant cette approche, les développeurs front-end gagnent en clarté sur les attentes métiers, tandis que les experts non techniques voient leurs besoins mieux traduits en solutions logicielles. Une méthode particulièrement utile pour les applications complexes où la compréhension du domaine est cruciale.
L'article propose une approche simplifiée du CQRS (Command Query Responsibility Segregation) en séparant clairement les opérations d'écriture (modification de données) et de lecture (récupération de données) au sein d'un service Node.js, sans recourir à des architectures complexes comme l'event sourcing ou des bases de données distinctes. L'idée centrale est de scinder un service monolithique en deux parties distinctes : une dédiée aux commandes (écritures) et une autre aux requêtes (lectures), afin d'éviter les conflits de responsabilités et d'améliorer la maintenabilité.
L'auteur illustre ce concept avec un exemple concret, comme un OrderService qui mélange des méthodes de gestion des commandes (validation, règles métier) et des méthodes de récupération de données (requêtes, transformations pour l'interface utilisateur). Cette séparation permet de faire évoluer indépendamment les deux parties en fonction des besoins changeants de l'application, réduisant ainsi la complexité et les risques d'erreurs. L'approche reste légère et applicable rapidement dans un projet existant.
Cet article explique le fonctionnement interne des grands modèles de langage (LLM) en se concentrant sur leur architecture basée sur les transformers. L’idée centrale est que ces modèles reposent sur des blocs de transformers répétés, dont les mécanismes clés (tokens, embeddings, attention, etc.) permettent de traiter le texte de manière efficace. Les différences entre modèles proviennent principalement des données d’entraînement, de leur taille et des ajustements post-formation.
L’auteur détaille le processus de conversion du texte en données exploitables par le modèle, notamment via la tokenisation, qui découpe les mots en sous-unités (souvent des sous-mots) pour équilibrer efficacité et généralisation. Les embeddings, matrices géantes associant à chaque token un vecteur de nombres, donnent un sens mathématique aux identifiants numériques. La positional encoding permet ensuite au modèle de comprendre l’ordre des tokens, tandis que les mécanismes d’attention et de multi-head attention facilitent les interactions entre eux.
Enfin, l’article aborde la prédiction du token suivant, cœur de la génération de texte, et distingue les éléments architecturaux communs (comme le residual stream ou la layer normalization) des variations propres à chaque modèle (vocabulaire, taille, données d’entraînement). L’objectif est de fournir une compréhension intuitive, sans entrer dans les détails mathématiques complexes.
L’article critique l’idée selon laquelle l’ère de l’IA rendrait la technique obsolète au profit d’une approche strictement "product-first". L’auteur souligne que, malgré les gains de productivité permis par l’IA, la qualité technique reste essentielle pour éviter des problèmes comme des performances médiocres, une architecture chaotique ou des solutions ingérables. Il met en garde contre l’usage abusif de l’argument "product-first" comme prétexte pour négliger la rigueur technique, même si des compromis sont parfois nécessaires pour livrer rapidement.
L’auteur, qui utilise massivement l’IA pour coder, rappelle que savoir quoi construire ne suffit pas : le comment compte toujours, surtout pour des projets complexes. Il cite Rich Hickey pour rappeler que la simplicité et la clarté technique restent des piliers, même avec des outils avancés. L’IA accélère le développement, mais ne dispense pas d’une réflexion sur l’architecture et la maintenabilité.
L’auteur partage son expérience sur la conception d’un monolithe modulaire pour un ERP de fabrication, où deux modules distincts (Catalogue et Collaboration) ont été séparés pour refléter des domaines métiers différents. Bien que cette séparation ait semblé logique au départ, des besoins fonctionnels ultérieurs ont progressivement rendu cette frontière poreuse, notamment en raison de dépendances croissantes entre les modules.
Le choix initial de communiquer via des événements pour maintenir un couplage faible a fonctionné pendant la migration, mais s’est révélé inadapté lorsque l’entreprise a exigé une cohérence immédiate des données. L’asynchronisme, initialement pertinent, a dû être remplacé par des appels synchrones et des transactions partagées, révélant que les deux modules auraient dû être fusionnés dès le départ.
L’auteur souligne que les signes avant-coureurs (comme les lectures fréquentes du Catalogue par le module Collaboration) n’ont pas été interprétés comme des indicateurs d’un problème d’architecture, mais comme des besoins fonctionnels normaux. Cette expérience illustre les défis des frontières modulaires dans un contexte métier évolutif.
L’auteur, développeur depuis 1983, partage son expérience de l’intégration de l’IA dans son workflow, notamment via le Markdown pour rédiger spécifications et architectures. Il critique à la fois le vibe coding (délégation aveugle à l’IA) et le rejet puriste de cette technologie, soulignant que la valeur réside désormais dans la conception et la supervision, pas dans la production de code brute.
Il utilise l’IA comme un outil collaboratif : pour des tâches simples, elle agit comme une exécutante rapide, tandis que pour les parties complexes, il supervise et valide, voire code lui-même. L’objectif est de maintenir une architecture compréhensible et maîtrisée, évitant ainsi les risques liés à des systèmes opaques ou dépendants de tarifs ou de disponibilités externes.
Enfin, il compare l’IA à un retour partiel du cycle en V, où la spécification redevient centrale. La confiance dans le code généré doit être proportionnelle à la capacité de le critiquer, et les rôles (spécification, validation, expertise) doivent rester clairs pour préserver la robustesse du système.
L’auteur explique comment Domain-Driven Design (DDD) a révolutionné sa vision de l’architecture logicielle, notamment pour les agents IA. Après des années de routine en développement, il découvre ce concept en lisant Domain-Driven Design d’Eric Evans, ce qui transforme sa manière d’aborder la complexité des systèmes. Son expérience précédente avec des microservices mal conçus, où les services manquaient de sens métier, l’a poussé à chercher une approche plus structurée.
Le livre l’a confronté à une réflexion approfondie sur la modélisation du domaine, où chaque détail (noms de classes, relations, effets de bord) devient crucial. Cette approche l’a ramené aux fondamentaux de la programmation orientée objet, avec une attention accrue à la clarté et à la cohérence du code. Il souligne que DDD a comblé un vide entre le développement et la compréhension du métier, contrairement à sa vision initiale où ces deux aspects étaient dissociés.
L’article explique comment structurer une architecture logicielle en trois couches (Domaine, Application, Infrastructure) en respectant la règle d’or centripète et le principe d’inversion de dépendance (DIP). L’idée centrale est que les dépendances doivent toujours aller du plus concret (infrastructure) vers le plus abstrait (domaine), jamais l’inverse, afin de préserver l’indépendance et la testabilité de la logique métier.
Le domaine concentre les règles métier, les agrégats (unités cohérentes comme un dossier de demande de subvention) et les value objects (objets immuables sans identité propre). Il définit des ports (interfaces) pour les besoins externes, sans jamais dépendre d’outils comme Doctrine ou Symfony. La couche applicative gère les cas d’usage via des handlers qui orchestrent les flux, tandis que l’infrastructure implémente concrètement ces ports (ex : adaptateurs pour Doctrine ou S3), sans jamais être importée par les couches supérieures.
Cette approche garantit que le métier reste isolé des détails techniques. Par exemple, un handler utilise DepositRequestRepositoryInterface (port défini dans le domaine) sans connaître son implémentation (DoctrineDepositRequestRepository en infrastructure). Ainsi, les changements d’outils n’affectent pas la logique métier, et les imports PHP respectent strictement la hiérarchie des couches.
L’article explique pourquoi les architectures CRUD (Create, Read, Update, Delete) compliquent les tests unitaires et augmentent la charge cognitive des développeurs. L’auteur souligne que la logique métier, dispersée dans des contrôleurs, services, FormType ou événements Doctrine, devient difficile à identifier et à tester, favorisant la duplication de code et les erreurs. Les modifications nécessitent de comprendre des interactions complexes, ralentissant le développement et augmentant le risque de régressions.
L’auteur illustre ce problème avec des exemples concrets en Symfony, où des règles métiers se cachent dans des couches techniques variées (validations dans les formulaires, effets de bord dans les écouteurs Doctrine). Cette dispersion empêche une couverture de test efficace, car les tests doivent souvent simuler des dépendances externes (bases de données, envoi d’emails) plutôt que de se concentrer sur la logique pure.
Enfin, l’article critique l’illusion des services génériques, qui masquent la complexité sans résoudre le problème de fond. La solution proposée est de distinguer clairement les contrats d’entrée (validation des données) des invariants métiers (règles de transition), afin de structurer le code de manière plus testable et maintenable.
L’article souligne les risques de l’anticipation excessive dans le développement logiciel, où la complexité naît souvent de besoins hypothétiques plutôt que réels. L’auteur illustre ce propos avec un exemple concret : une fonctionnalité rendue paramétrable par prudence, mais jamais utilisée, entraînant deux ans de maintenance inutile. Cette approche, bien que courante, alourdit inutilement les systèmes en augmentant le temps de développement, les risques de bugs et la difficulté de maintenance.
L’auteur explique que les abstractions prématurées, comme des interfaces génériques ou des systèmes de configuration superflus, compliquent le code sans apporter de valeur réelle. Ces choix, motivés par une anticipation incertaine, rendent souvent le logiciel plus difficile à comprendre et à faire évoluer. De plus, la solution imaginée pour un besoin hypothétique peut s’avérer inadaptée, forçant des adaptations coûteuses plutôt qu’une refonte optimale.
Pour éviter ces écueils, l’auteur prône un principe simple : construire uniquement ce qui est nécessaire aujourd’hui, en se basant sur des besoins avérés plutôt que sur des scénarios futurs incertains. Cette approche réduit la complexité, facilite la maintenance et permet d’adapter le code plus efficacement lorsque les besoins réels se présentent.
Retour d’expérience du DevFest Nantes 2025 décrivant un événement dense et stimulant, marqué par une forte participation des équipes et une grande diversité de formats (conférences, ateliers, Unconference favorisant les échanges ouverts). L’accent est mis sur la richesse des discussions techniques et humaines, ainsi que sur l’intérêt de ces formats interactifs pour partager des retours concrets et confronter les pratiques entre professionnels.
Parmi les sujets abordés, plusieurs thématiques ressortent : l’observabilité avec OpenTelemetry, les enjeux d’architecture logicielle (scalabilité, résilience, sécurité), l’impact environnemental du numérique et les pratiques de sobriété, ainsi que des retours d’expérience sur l’organisation des équipes et les méthodes de travail. Certaines conférences utilisent des analogies issues du jeu vidéo pour vulgariser des concepts complexes d’architecture ou de monitoring, rendant ces sujets plus accessibles et concrets.
L’ensemble est perçu comme inspirant et directement applicable, avec des idées réutilisables en entreprise, aussi bien sur le plan technique que sur les dimensions organisationnelles et sociétales du développement logiciel.
Cet outil permet de générer des diagrammes d'architecture système esthétiques et thématiques sombres sous forme de fichiers HTML/SVG autonomes, directement via une compétence pour l'IA Claude. Il suffit de décrire son architecture en langage naturel pour obtenir un diagramme professionnel en quelques secondes, sans compétences en design ni logiciel spécifique.
L'installation repose sur trois étapes simples : télécharger un fichier ZIP, l'importer dans les paramètres des compétences de Claude (nécessitant un abonnement Pro ou supérieur), puis décrire son architecture via une analyse automatique de codebase, une rédaction manuelle ou une demande de modèle générique. L'IA produit ensuite un fichier HTML prêt à l'emploi, modifiable à la volée par des instructions en conversation.
Le projet propose des exemples concrets pour des cas d'usage variés (applications web, architectures serverless AWS ou microservices) et permet des itérations rapides en ajustant la description initiale. Les fichiers générés sont partageables et compatibles avec tout navigateur.
L’architecture d’un système de modules JavaScript est une décision clé pour structurer une application, car elle détermine les frontières entre les composants et influence la maintenabilité du code. Avant les modules, JavaScript dépendait du scope global, entraînant des conflits de variables et des écrasements de scripts. Les modules, comme ESM (ECMAScript Modules) ou CommonJS, permettent de créer des portées privées et de contrôler explicitement les exports, mais leur conception impacte différemment la flexibilité et l’analysabilité du code.
ESM et CommonJS diffèrent par leur approche : CommonJS offre une flexibilité accrue avec des imports dynamiques (via require()), tandis qu’ESM impose des règles strictes (imports statiques en haut de fichier) pour faciliter l’analyse statique et le tree-shaking, réduisant ainsi la taille des bundles. Cette rigidité améliore la prédictibilité des dépendances, mais limite certaines pratiques comme les imports conditionnels.
Enfin, la gestion des modules reflète l’architecture globale d’un projet, influençant les dépendances, la collaboration d’équipe et la scalabilité. Une conception réfléchie des modules dès le départ évite des problèmes de maintenance futurs, faisant de ce choix une étape fondatrice pour tout développement JavaScript.
L’étude du codebase d’etcd, un magasin clé-valeur distribué écrit en Go, a inspiré l’auteur à repenser ses pratiques en PHP. Il met en avant des principes d’architecture logicielle applicables quel que soit le langage, comme la définition stricte des contrats d’API via des DTO typés pour éviter les ambiguïtés et les erreurs en production.
L’auteur souligne également l’importance de la séparation des responsabilités, où chaque service ou classe ne doit accomplir qu’une seule tâche, évitant ainsi les contrôleurs monolithiques difficiles à maintenir. Enfin, il compare les intercepteurs d’etcd aux écouteurs d’événements et au système de messages de Symfony, montrant comment une composition modulaire améliore la lisibilité et la maintenabilité du code.
L’article explique pourquoi le vibe coding (développement basé uniquement sur l’intuition et les prompts sans revue de code) a échoué en production, malgré son engouement initial. Andrej Karpathy, son inventeur, a récemment remplacé ce concept par l’agentic engineering : une approche où l’IA génère le code sous supervision humaine stricte, avec une responsabilité claire sur l’architecture, la qualité et la sécurité. L’auteur souligne que le problème n’était pas l’outil, mais l’absence de discipline, conduisant à du code non maintenable, des failles de sécurité et une dette cognitive accrue. Une lecture essentielle pour comprendre l’évolution des pratiques de développement assisté par IA en 2026.
L’article explore l’application de la pensée systémique en architecture d’entreprise, en s’appuyant sur des exemples concrets comme l’impact des bâtiments sur les oiseaux ou l’ajout d’arbres en ville. L’auteur souligne la complexité des interactions dans les organisations, comparables à des Unknown Unknowns (inconnues inconnues), difficiles à anticiper. Il présente la Matrice de Rumsfeld (connus/connus, connus/inconnus, inconnus/connus, inconnus/inconnus) pour structurer la réflexion stratégique, et propose les diagrammes de boucles causales en post-mortem pour analyser les effets émergents. Une approche pragmatique pour naviguer dans l’incertitude des systèmes complexes.
Cet article de Towards Data Science explore le problème de la "boîte noire" dans le code généré par l'IA. Bien que l'IA améliore initialement la productivité des équipes de développement, le code généré devient rapidement difficile à maintenir en raison de son manque de structure. Les principaux problèmes incluent la tendance à tout regrouper dans un seul module, les dépendances circulaires et implicites, l'absence de contrats explicites et une documentation qui explique l'implémentation plutôt que l'utilisation. Un exemple concret illustre comment une génération non structurée peut créer un système de notifications monolithique difficile à modifier, contrairement à une approche structurée qui décompose le système en composants indépendants. L'article souligne que le problème n'est pas l'IA en soi, mais plutôt l'architecture résultante.
L'article présente le concept de "FinOps by Design", une approche proactive pour intégrer la gestion des coûts cloud dès la conception architecturale. Il souligne que les coûts sont souvent négligés jusqu'à la mise en production, entraînant des dépenses inutiles et des dépassements budgétaires. Le FinOps by Design propose d'anticiper et de modéliser les coûts dès les premières étapes, en les traitant comme une exigence non fonctionnelle majeure. Les principes clés incluent un design orienté usage, une scalabilité maîtrisée pour éviter le surdimensionnement, et une gouvernance FinOps intégrée dès l'Infrastructure as Code (IaC). L'article met en avant des outils comme Terraform combiné à InfraCost pour estimer les coûts avant le déploiement, soulignant l'importance d'une planification financière rigoureuse dès le début du cycle de vie applicatif.