m2vic/code-simple

Écrire le code le plus simple et le plus lisible qui produit le résultat demandé, en supprimant toute logique compliquée, abstraction ou élément superflu qui ne modifie pas ce résultat.

Qu'est-ce que code-simple ?

Cette compétence guide un agent IA à produire un code simple, lisible et maintenable, en se concentrant strictement sur les exigences actuelles sans ajouter d'extras inutiles. Elle insiste sur le fait qu'un programme que l'on comprend rapidement est meilleur qu'un autre qui produit le même résultat, et que chaque classe, helper, paramètre ou couche doit justifier son existence en changeant ce que le programme fait réellement. La compétence détaille un processus en cinq étapes : énoncer le travail, écrire la version ennuyeuse d'abord, exécuter le test de suppression, tester et garder le test, et faire un rapport simple. Elle fournit également des principes concrets sur ce à quoi ressemble la simplicité : construire pour les besoins d'aujourd'hui, atteindre les objectifs de qualité de la manière la plus simple, utiliser la construction la plus simple qui fonctionne, garder le flux droit, laisser les petites répétitions telles quelles, nommer les choses pour un humain, commenter uniquement le pourquoi, gérer les échecs de manière bruyante, vérifier les nombres provenant de l'extérieur avant de faire de l'arithmétique avec eux, et n'ajouter aucun extra. Elle s'applique à toute modification de code existante, en suivant les conventions du projet et en effectuant le plus petit changement possible. La compétence inclut des exemples concrets (comme le calcul d'un prix final avec réduction membre et frais de port) montrant la différence entre un code sur-conçu et un code simple et direct. Elle précise enfin ce que simple ne signifie pas : ne jamais sacrifier la correction, la sécurité, la précision monétaire, les performances demandées ou une abstraction explicitement demandée pour gagner des lignes.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/m2vic/claude-skills/tree/HEAD/plugins/simple-code/skills/simple-code

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

Code Simple

Deux programmes qui donnent le même résultat ne sont pas égaux : celui qu'une personne comprend le plus rapidement est meilleur. Chaque classe, helper, paramètre et couche est quelque chose que le prochain lecteur doit apprendre, donc chacun doit mériter sa place en changeant ce que le programme fait.

L'objectif est un code qu'un nouveau coéquipier peut lire de haut en bas une fois, expliquer et modifier en toute sécurité.

Comment travailler

  1. Énoncer le travail. Qu'est-ce qui entre, qu'est-ce qui sort, quelles règles et cas limites ont été demandés, et tout objectif de qualité ou conception nommé par l'utilisateur. Tout cela sont des exigences. Travaillez à partir de cette liste, pas de ce dont le code pourrait avoir besoin un jour.
  2. Écrire d'abord la version ennuyeuse. Fonctions simples, instructions if, boucles et données littérales, dans l'ordre dont une personne décrirait les étapes. C'est la conception que vous conservez sauf si elle échoue à une exigence énoncée.
  3. Exécuter le test de suppression. Pour chaque classe, helper, paramètre, constante, import, branche et try : supprimez-le mentalement. Si chaque exigence énoncée, y compris les objectifs de qualité, est toujours satisfaite, supprimez-le pour de bon.
  4. Le tester et conserver le test. Couvrez chaque règle et cas limite énoncé dans un petit fichier de test simple à côté du code, en suivant les conventions du projet, sauf si l'utilisateur dit le contraire. Les tests montrent au prochain lecteur quelles sont les règles et rendent les modifications sûres, ils font donc partie du travail et non un supplément.
  5. Faire un rapport simple. Dites ce que vous avez construit. Si vous avez délibérément omis quelque chose, nommez-le en une ligne ("Pas de CLI ni de journalisation, car aucun n'a été demandé"), afin que l'utilisateur puisse le demander.

À quoi ressemble la simplicité

Construire pour les exigences d'aujourd'hui. Un "on pourrait ajouter plus tard" qui passe n'est pas une fonctionnalité à construire maintenant. Le code simple est le plus facile à étendre, car il n'y a rien à contourner. Ajouter un coupon devrait signifier ajouter une ligne, pas d'abord apprendre un framework.

Atteindre les objectifs de qualité énoncés de la manière la plus simple. Lorsqu'une demande dit "prêt pour la production", "robuste", "évolutif" ou "niveau entreprise", demandez ce qui pourrait vraiment mal tourner avec ce code en utilisation, puis gérez ces choses directement : les entrées incorrectes sont rejetées, les échecs sont visibles, rien n'est perdu silencieusement, l'argent est correct au centime près. Ces mots appellent à cette attention. Ils n'appellent pas à des couches, systèmes de plugins ou frameworks.

Livrer une conception demandée par l'utilisateur. Lorsque quelqu'un demande une architecture ou une structure spécifique, donnez-lui la plus petite forme utile, et ne répondez pas qu'il faut attendre. Si d'autres formes arrivent, par exemple, la conception pourrait être des fonctions de vérification partagées que la prochaine forme réutilise, avec une ligne sur la façon d'en ajouter une. Arrêtez-vous avant un moteur dont seuls des cas imaginés auraient besoin.

Utiliser la construction la plus simple qui fonctionne, dans cet ordre approximatif :

  • une valeur ou un dictionnaire littéral avant un système de configuration
  • if/elif ou un dictionnaire de correspondance avant un registre, une stratégie, une fabrique ou un système de plugins
  • une fonction avant une classe ou une structure avec des méthodes ; n'en ajoutez une que lorsqu'elle détient un état que plusieurs opérations partagent
  • un type concret avant une interface ou des génériques ; n'ajoutez ceux-ci que lorsque deux implémentations ou types réels en ont besoin aujourd'hui
  • du code séquentiel avant des goroutines et des canaux, sauf si la concurrence est une exigence
  • la bibliothèque standard et les helpers déjà dans le projet avant une nouvelle dépendance

Garder le flux droit. Retournez tôt au lieu d'imbriquer ; plus d'environ trois niveaux de profondeur signifie généralement que le flux peut être aplati. Faites une chose par ligne. Préférez une boucle lisible à une compréhension imbriquée, des ternaires chaînés, reduce, ou une expression régulière astucieuse. Évitez la métaprogrammation, la réflexion et les décorateurs personnalisés, sauf si la tâche les concerne spécifiquement.

Laisser les petites répétitions telles quelles. Trois lignes similaires sont souvent plus claires qu'un helper avec des drapeaux. Extrayez une fonction lorsqu'elle donne un nom approprié à une véritable idée ou lorsque la logique doit rester synchronisée, pas simplement parce que deux lignes se ressemblent. N'ajoutez pas de paramètres qu'un seul appelant utilise ou que personne n'a demandés.

Nommer les choses pour un humain. Utilisez des mots complets et ordinaires (frais_port, pas fp ou ContexteCalculFrais). Un bon nom élimine le besoin d'un commentaire.

Commenter uniquement le pourquoi. Notez une règle ou contrainte surprenante. Évitez les commentaires qui répètent le code, les bannières de section et les longues docstrings qui reformulent la signature.

Gérer les échecs qui peuvent se produire, et échouer bruyamment. Validez ce que les exigences ou une frontière réelle (entrée utilisateur, réseau, fichiers) imposent, et retournez une erreur claire pour une entrée incorrecte au lieu de produire une réponse erronée plausible. Si le code ignore ou supprime des données, rendez cela visible pour celui qui l'exécute, par exemple avec un compteur dans une ligne de journal. N'attrapez pas une exception juste pour la relancer, et ne vous prémunissez pas contre des états que le code ne peut pas atteindre.

Vérifier les nombres provenant de l'extérieur avant de faire de l'arithmétique avec eux. Une quantité, un montant ou un comptage provenant d'une requête peut être énorme, et son ajout ou sa multiplication peut déborder en une valeur petite ou négative qui passe tous les contrôles ultérieurs. Comparez la valeur entrante avec sa limite (stock, un maximum) avant de l'ajouter à quoi que ce soit, et ajoutez un test qui envoie la plus grande valeur que le type peut contenir. C'est un if, pas du code supplémentaire.

Décider ce qu'un redémarrage fait au milieu d'une modification en plusieurs étapes. Lorsque le code modifie un état sauvegardé, appelle quelque chose de lent ou d'externe (comme un fournisseur de paiement), puis modifie à nouveau l'état, demandez ce qui se passe si le processus s'arrête entre ces étapes. Enregistrez un état intermédiaire clair (comme en_attente) avant l'appel. Au redémarrage, ne devinez pas : ne défaites pas une étape qui a peut-être réussi (comme retourner du stock pour un débit qui a peut-être été effectué), et ne rouvrez pas le travail pour qu'une nouvelle tentative puisse débiter deux fois. Laissez l'enregistrement dans son état intermédiaire, gardez-le bloqué et rendez-le visible, par exemple en journalisant combien sont en attente au démarrage, afin qu'une personne puisse le résoudre. Écrivez cette règle en une ou deux lignes de la conception et testez-la en redémarrant avec un enregistrement en attente.

N'ajouter aucun extra. Pas de CLI, journalisation, configuration, tentatives, mise en cache, métriques ou hiérarchies de types, sauf s'ils ont été demandés, ou si le travail ou un objectif énoncé ne peut pas être atteint sans eux. Un code qui s'exécute sans surveillance, par exemple, a besoin d'un moyen de signaler les problèmes.

Lors de la modification de code existant

Suivez les conventions du projet et effectuez la plus petite modification qui fait le travail. Ne restructurez pas le code voisin et n'introduisez pas un nouveau motif en passant. Gardez le code compliqué qui fonctionne, sauf si le simplifier est la tâche ou si votre modification l'exige ; s'il semble supprimable, mentionnez-le plutôt.

Ce que simple ne signifie pas

N'abandonnez jamais aucun de ces éléments pour gagner des lignes :

  • Comportement correct, y compris chaque règle et cas limite énoncé
  • Sécurité : validation des entrées aux frontières de confiance, requêtes sécurisées, pas de secrets dans le code
  • Précision qui compte : l'argent doit être correct au centime près, y compris les cas de demi-cent, et un test doit le prouver. Utilisez la méthode la plus simple qui le fait. Un flottant avec un petit helper d'arrondi qui élimine le bruit binaire est acceptable lorsque les prix ont quelques décimales et qu'un flottant traverse de toute façon la frontière de la fonction. Recourez aux centimes entiers ou aux fractions exactes (comme big.Rat) uniquement lorsqu'une règle énoncée les nécessite, ou lorsqu'un test montre que la méthode plus simple obtient un résultat erroné
  • Performance que la tâche a réellement demandée ou qu'une mesure a montré être importante
  • Une abstraction que l'utilisateur a explicitement demandée ; construisez-la, dans sa forme la plus simple

Moins de lignes n'est pas non plus l'objectif. Le golf de code est aussi difficile à lire que le sur-engineering, donc préférez la version plus longue lorsqu'elle est plus claire. Une longue fonction qui fait tout n'est pas simple : lorsqu'une fonction mélange des étapes distinctes (comme lire, analyser et résumer), donnez à chaque étape une fonction bien nommée. Lorsqu'un problème a une complexité réelle, conservez-la, isolez-la à un endroit bien nommé et expliquez pourquoi dans un commentaire court.

Exemple

Tâche : appliquer une réduction membre et facturer 5 de port pour les commandes de moins de 50.

Évitez ceci. Cela donne le même résultat avec beaucoup plus à lire :

type DiscountStrategy interface {
	Apply(amount float64) float64
}

type MemberDiscount struct{}

func (MemberDiscount) Apply(amount float64) float64 {
	return amount * 0.95
}

type PriceCalculator struct {
	Strategy          DiscountStrategy
	ShippingThreshold float64
	ShippingFee       float64
}

func (c PriceCalculator) Calculate(amount float64) float64 {
	discounted := c.Strategy.Apply(amount)
	if discounted < c.ShippingThreshold {
		return discounted + c.ShippingFee
	}
	return discounted
}

Écrivez ceci :

func FinalPrice(amount float64, isMember bool) float64 {
	if isMember {
		amount = amount * 0.95
	}
	if amount < 50 {
		amount = amount + 5
	}
	return amount
}

Ajouter une réduction VIP plus tard prend un if de plus, et personne n'a eu à apprendre une interface et trois types pour le faire.

Skills associés