Anti-modèles à éviter dans votre code

Chaque développeur souhaite écrire du code structuré, simplement planifié et joliment commenté. Il existe même une myriade de modèles de conception qui nous donnent des règles claires à suivre et un cadre à garder à l'esprit.

Mais nous pouvons toujours trouver des anti-patterns dans des logiciels qui ont été écrits il y a quelque temps ou qui ont été écrits trop rapidement.

Un hack de base inoffensif pour résoudre rapidement un problème peut créer un précédent dans votre base de code. Il peut être copié à plusieurs endroits et se transformer en un anti-motif que vous devez traiter.

Alors, qu'est-ce qu'un anti-modèle?

Dans les logiciels, anti-pattern est un terme qui décrit comment NE PAS résoudre les problèmes récurrents dans votre code. Les anti-modèles sont considérés comme une mauvaise conception de logiciel et sont généralement des correctifs inefficaces ou obscurs.  

Ils ajoutent généralement aussi la «dette technique» - c'est-à-dire du code que vous devez revenir et corriger correctement plus tard.

Les six anti-modèles dont je vais parler dans cet article sont le code spaghetti , le marteau d'or , l' ancre de bateau , le code mort , la prolifération du code et l' objet divin .

Code spaghetti

Spaghetti Code est l'anti-motif le plus connu. C'est du code avec une structure peu à zéro.

Rien n'est modularisé. Il y a des fichiers aléatoires éparpillés dans des répertoires aléatoires. L'ensemble du flux est difficile à suivre et est totalement emmêlé (comme des spaghettis).

Normalement, c'est un problème où quelqu'un n'a pas soigneusement réfléchi au flux de son programme à l'avance et vient de commencer à coder.

Qu'est ce que ça fait?! Je ne peux pas suivre ça

image.png

Ce n'est pas seulement un cauchemar de maintenance, mais cela rend presque impossible d'ajouter de nouvelles fonctionnalités.

Vous allez constamment casser des choses, ne pas comprendre la portée de vos changements ou donner des estimations précises pour votre travail car il est impossible de prévoir les innombrables problèmes qui surgissent lors de telles archéologies / conjectures.

Vous pouvez en savoir plus ici sur l' anti-motif Spaghetti Code .

Marteau d'or

"Je suppose qu'il est tentant, si le seul outil dont vous disposez est un marteau, de tout traiter comme s'il s'agissait d'un clou." Abraham Maslow

Imaginez un scénario avec moi: votre équipe de développement est très, très compétente dans la toute nouvelle architecture Hammer. Cela a fonctionné à merveille pour tous vos problèmes passés. Vous êtes la première équipe mondiale d'architecture Hammer.

Mais maintenant, d'une manière ou d'une autre, tout finit toujours par utiliser cette architecture. Une vis à tête plate? Marteau. Vis à tête Phillips? Marteau. Vous avez besoin d'une clé Allen? Non tu ne le fais pas, martèle-le.

Vous commencez à appliquer une approche architecturale qui ne correspond pas tout à fait à vos besoins, mais qui fait le travail. Vous êtes trop dépendant d'un modèle et devez apprendre le meilleur outil pour le meilleur travail.

Votre programme dans son ensemble pourrait finir par prendre un sérieux coup de performance parce que vous essayez de percer un carré en forme de cercle. Vous savez qu'il faut deux fois plus de temps pour coder et exécuter un programme en utilisant l'architecture hammer pour ce problème, mais c'est plus facile et c'est ce avec quoi vous êtes à l'aise.

Ce n'est pas non plus très prévisible. Différentes langues ont des solutions communes aux problèmes auxquels elles sont confrontées et leurs propres normes. Vous ne pouvez pas appliquer toutes les règles qui ont bien fonctionné pour vous dans une langue à l'autre, sans aucun problème.

Ne négligez pas l'apprentissage constant de votre carrière. Choisissez la bonne langue pour votre problème. Pensez à l'architecture et repoussez votre zone de confort. Recherchez et étudiez de nouveaux outils et de nouvelles façons d'aborder les problèmes auxquels vous faites face.

Vous pouvez en savoir plus ici sur l' anti-motif Golden Hammer .

Ancre de bateau

L' anti-pattern Boat Anchor est l'endroit où les programmeurs laissent le code dans la base de code car ils pourraient en avoir besoin plus tard.

Ils ont codé quelque chose légèrement hors spécifications et ce n'est pas encore nécessaire, mais ils sont sûrs qu'ils le feront le mois prochain. Ils ne veulent donc pas le supprimer. Envoyez-le en production et plus tard quand ils en ont besoin, ils peuvent le faire fonctionner rapidement.

Mais cela provoque des cauchemars de maintenance dans la base de code qui contient tout ce code obsolète. Le gros problème est que leurs collègues auront du mal à déterminer quel code est obsolète et ne change pas le flux, par rapport au code qui le fait.

Imaginez que vous êtes sur un correctif et que vous essayez désespérément de déterminer ce qui est responsable de l'envoi des détails de la carte des clients à l'API pour retirer des fonds de leur banque. Vous pourriez perdre du temps à lire et à déboguer du code obsolète, sans vous rendre compte que vous n'êtes même pas au bon endroit dans la base de code.

Le dernier problème est que le code obsolète rallonge votre temps de construction et vous risquez de confondre code fonctionnel et code obsolète. Vous pourriez même commencer à "l'activer" par inadvertance en production.

Maintenant, vous pouvez probablement voir pourquoi on l'appelle l'anti-modèle d'ancre de bateau - il est lourd à transporter (ajoute une dette technique) mais ne fait rien (littéralement, le code ne sert à rien, il ne fonctionne pas).

Vous pouvez en savoir plus ici sur l' anti-motif d' ancre de bateau .

Code mort

Avez-vous déjà eu à regarder du code écrit par quelqu'un qui ne travaille plus dans votre entreprise? Il y a une fonction qui ne semble pas faire quoi que ce soit. Mais il est appelé de partout! Vous demandez autour de vous et personne d'autre n'est sûr de ce qu'il fait, mais tout le monde est trop inquiet pour le supprimer.

Parfois, vous pouvez voir ce qu'il fait, mais le contexte manque. Vous êtes capable de lire et de comprendre le flux, mais pourquoi? Il ne semble plus que nous ayons besoin d'atteindre ce point de terminaison. La réponse est toujours la même pour chaque utilisateur différent.

This is commonly described as the Dead code anti-pattern. When you can't see what is "actual" code necessary to the flow and successful execution of your program, versus what was only needed 3 years ago, and not now.

This particular anti-pattern is more common in proof on concept or research code that ended up in production.

One time at a tech meet up I met a guy who had this exact problem. He had tons of dead code, which he knew was dead, and lots he suspected was dead. But he could not get permission from management to ever remove all the dead code.

He referred to his approach as Monkey testing, where he started to comment out and turn off things to see what blew up in production. Maybe a little too risky!

If you don't fancy Monkey testing your production app, try to frame technical debt to management as "technical risk" to better explain why you think it's so important to tidy up.

Or even write down everything your particular module/section does you want to re-write, and take an iterative approach to remove piece by piece the dead code. Checking every time you haven't broken anything.

You don't have to drop a huge rewrite with thousands of changes. But you will either understand why it's so crucial and document why it's needed, or delete the dead code as you desired.

You can read more here about the Dead code anti-pattern.

Proliferation of Code

Objects or modules regularly communicate with others. If you have a clean, modularised codebase you often will need to call into other separate modules and call new functions.

The Proliferation of Code anti-pattern is when you have objects in your codebase that only exist to invoke another more important object. Its purpose is only as a middleman.

This adds an unnecessary level of abstraction (adds something that you have to remember) and serves no purpose, other than to confuse people who need to understand the flow and execution of your codebase.

A simple fix here is to just remove it. Move the responsibility of invoking the object you really want to the calling object.

You can read more here about the Proliferation of Code anti-pattern.

God Object

If everywhere in your codebase needs access to one object, it might be a God object.

God objects do too much. They are responsible for the user id, the transaction id, the customer's first and last name, the total sum of the transaction, the item/s the user is purchasing...you get the picture.

It is sometimes called the Swiss Army Knife anti-pattern because you only really need it to cut some twine, but it also can be a nail file, saw, pair of tweezers, scissors, bottle opener and a cork screw too.

In this instance you need to separate out and modularise your code better.

Programmers often compare this problem to asking for a banana, but receiving a gorilla holding a banana. You got what you asked for, but more than what you need.

The SOLID principles explicitly discuss this in object orientated languages, to help us model our software better (if you don't know what the SOLID principles are, you can read this article).

The S in the acronym stands for Single Responsibility - every class/module/function should have responsibility over one part of the system, not multiple.

You can see this problem over and over again, how about the below interface?

interface Animal { numOfLegs: string; weight: number; engine: string; model: string; sound: string; claws: boolean; wingspan: string; customerId: string; } 

Can you see by even just briefly scanning this interface that the responsibility of this is far too broad, and needs refactoring? Whatever implements this has the potential to be a God object.

How about this?

 interface Animal { numOfLegs: string; weight: number; sound: string; claws: boolean; } interface Car { engine: string; model: string; } interface Bird { wingspan: string; } interface Transaction { customerId: string; } 

Interface segregation will keep your code clear about where the responsibilities lie, and stop forcing classes that only need wingspan to also implement the engine, customerId and model  and so on.

Vous pouvez en savoir plus ici sur l' anti-modèle d' objet de Dieu .

Conclusion

Dans toute grande base de code, il existe un équilibre constant entre la gestion de la dette technique, le démarrage d'un nouveau développement et la gestion d'une file d'attente de bogues pour votre produit.

J'espère que cet article vous a donné un œil pour repérer quand vous pourriez descendre dans le terrier d'un anti-motif, et quelques outils pour le résoudre proprement.

Je partage mes écrits sur Twitter si vous avez apprécié cet article et que vous souhaitez en savoir plus.