Article original : How two software development principles can save your project

Par Jordy Baylac

Introduction

Dans cet article, je vais me concentrer sur l'explication de la manière dont un modèle de conception (Inversion de Contrôle) et une pratique (YAGNI) peuvent réduire la possibilité d'avoir un projet logiciel échoué. Vous pouvez commencer à appliquer ces techniques dès maintenant.

Si vous êtes un Engineering Manager, cet article est une bonne lecture si vous souhaitez réduire la volatilité du coût marginal des fonctionnalités ?.

Inversion de Contrôle (IoC)

Voulais-je dire Injection de Dépendances ? Pas vraiment, mais nous pouvons utiliser l'Injection de Dépendances comme outil pour atteindre l'Inversion de Contrôle entre les dépendances.

IoC peut aider à changer la direction des dépendances. Cela peut aider dans les situations où le composant A dépend du composant B, et maintenant vous voulez que A ne soit pas conscient des détails d'implémentation de B.

Situation actuelle

Image Le composant A dépend du composant B.

Situation cible

Image Le composant A ne dépend pas des détails d'implémentation du composant B.

Avec cette dernière approche, le composant A ne dépend pas des spécificités du composant B. En fait, de nouvelles implémentations de IBehaviourB pourraient être ajoutées au projet sans même toucher au composant A.

Exemple de code

Une application inconnue ayant trois couches bien connues.

UI -> REST API -> Database

En zooming sur l'API REST, nous avons trouvé la classe UsersController. Nous avons noté qu'elle lit et écrit depuis/vers une Base de données SQLServer. Voici une implémentation possible en C# :

Si vous considérez que la solution ci-dessus n'est pas un bon design, vous avez raison ?.

Dans l'exemple, UsersController est fortement couplé avec l'implémentation SQLServer. La méthode postUser rend difficile l'écriture de Tests (rappelez-vous qu'un test unitaire ne doit pas toucher les bases de données ou les services externes). À mesure que l'application évolue, il y aura une forte dépendance à la bibliothèque SQLServer spécifique utilisée. Si quelqu'un décide de diviser l'application par domaine, il peut être trop tard ?.

Cet exemple de code correspond à la "situation actuelle" présentée au début de l'article. Dans ce cas :

  • A = UsersController
  • B = System.Data.SqlClient sur .NET

Mais attendez...

Et si nous appliquions l'Inversion de Contrôle pour que UsersController ne dépende pas d'une implémentation spécifique de SQLServer ? Et si nous rendions l'API REST inconsciente de la couche de Persistence que nous utilisons ?

?, ok, faisons-le :

Image

20 jours plus tard ?:

Pour simplifier, nous avons désigné trois fichiers sources, mais en pratique, ils pourraient être divisés ou situés dans des assemblages ou dossiers séparés. Cette solution correspond à la "situation cible" présentée au début. Dans ce cas :

  • A = UsersController
  • B = SQLUserService
  • IBehaviourB = IUserService.

Nous l'avons fait !

Oh, mais attendez, comment la dépendance IUserService est-elle injectée dans le constructeur de UsersController ? Eh bien, les détails d'implémentation de cela sont hors du cadre de cet article. Cependant, si vous êtes intéressé, consultez le tutoriel que j'ai ajouté à la fin.

Avantages

  • Notre architecture est ouverte aux extensions. De plus, nous avons réduit la nécessité de modification dans les classes existantes. Principe Open/Close ?
  • Les tests sont faciles à écrire. Nous pouvons injecter un mock UserService lors du test de UsersController ?
  • La logique métier n'est pas couplée et ne dépend d'aucune stratégie de persistence. 

YAGNI

Vous n'en aurez pas besoin !

Je considère que chaque développeur devrait adopter YAGNI comme l'une de ses pratiques principales. Ce principe peut vous sauver de l'ingénierie excessive et du code inutilisé (intouchable). Il peut aussi sauver votre emploi.

Une petite histoire amusante :

J'ai travaillé sur un projet où les architectes logiciels ont décidé de représenter presque toutes les colonnes booléennes dans la base de données avec un type de données char. Au moins, ils utilisaient l'anglais — true était stocké comme "Y", false avec "N". Cela a du sens, n'est-ce pas ? Lorsque j'ai demandé comment une solution aussi magique avait été conçue, ils ont répondu :

"De cette manière, nous sommes ouverts à la possibilité qu'un troisième état puisse arriver."

Je n'ai jamais compris comment une chose vrai/faux peut avoir un troisième état (peut-être pensaient-ils aux qubits). Comme vous pouvez le noter, cela s'est avéré être une très mauvaise décision et les conséquences étaient présentes partout dans le code. J'ai trouvé des choses comme :

if (supportVisa === "Y" || supportVisa === "y") { ...

La lisibilité du code était affectée, et les requêtes SQL étaient également affectées.

Mais cela ne s'est pas arrêté là. Avec le temps, le logiciel a ajouté l'internationalisation à ses interfaces utilisateur. Certaines configurations et catalogues étaient fournis par le client lui-même en utilisant une application GUI. Nous en sommes arrivés au point où certaines de nos colonnes booléennes avaient "S" et "N" (Si et No en espagnol).

Le code était vraiment difficile à maintenir. Je ne veux pas parler de la solution qu'ils ont proposée ?.

Conclusions

Selon Uncle Bob, les bons développeurs essaieront de maximiser le nombre de décisions non prises. N'écrivez pas quelque chose que vous croyez être utile dans six mois. Au lieu de cela, attendez les six mois, jetez un coup d'œil à votre architecture, voyez combien elle a évolué, et ensuite, faites le travail. Appliquez YAGNI.

Vous devriez gérer vos dépendances correctement. L'Inversion de Contrôle vous guidera dans cette voie.

J'espère entrer dans votre conscience et vous aider à devenir un meilleur développeur.

"N'importe quel idiot peut écrire du code qu'un ordinateur peut comprendre. Les bons programmeurs écrivent du code que les humains peuvent comprendre." — Martin Fowler

Lire plus sur

Veuillez partager vos pensées et poser toutes vos questions. Je serai ravi d'y répondre. ? Retrouvez-moi sur Twitter.