Motivation pour un code propre
Quelle que soit l'ampleur du projet logiciel, nous devons faire partie de n'importe quelle équipe, grande ou petite. Par conséquent, il est très important que : le code, écrit par nous, soit lisible et développable par d'autres développeurs.
"Big" Dave Thomas , (fondateur d'OTI, le parrain de la stratégie Eclipse) définit le code propre avec ces phrases :
Un code propre peut être lu et amélioré par un développeur autre que son auteur d'origine . Il a des tests unitaires et d'acceptation. Il a des noms significatifs. Il fournit une façon plutôt que plusieurs façons de faire une chose. Il a des dépendances minimales , qui sont explicitement définies, et fournit une API claire et minimale.
D'un autre côté, même si nous allons maintenir le projet seul, nous pouvons avoir besoin de faire des développements supplémentaires pour n'importe quel module du projet des mois ou des années plus tard. Il est nécessaire de pouvoir comprendre, en un coup d'œil, quelle tâche remplit le code écrit il y a des années, quels modules du projet ils servent, pour protéger la santé mentale du développeur et s'assurer que les autres modules ne sont pas affectés par le nouveau développement.
N'importe quel imbécile peut écrire du code qu'un ordinateur peut comprendre. Les bons programmeurs écrivent du code que les humains peuvent comprendre. Martin Fowler
Pourquoi un code propre est-il nécessaire ?
Il n'est pas difficile de prédire ce qui va se passer lors du développement avec du code impur. Je veux parler de certains des problèmes auxquels nous serons confrontés.
Si le code n'est pas propre ;
- Génère de la dette technique (Si vous voulez jeter un œil : «https://en.wikipedia.org/wiki/Technical_debt”). Nous pouvons parler de la gestion des dettes techniques sous une autre rubrique, mais il peut y avoir de nombreuses raisons à la dette technique. Le premier allumeur de cette mèche est également codé non proprement.
- Nous rencontrons des blocs de code qui deviennent non maintenables, avec le temps, le projet peut également devenir non maintenable.
- Cela coûterait cher au développement. Le coût de développement serait plus élevé qu'il ne devrait l'être. Si l'équipe de développement ne peut pas prévoir le coût, c'est une indication claire que nous avons un projet qui n'a pas été proprement développé.
- La confusion grandit. Avec chaque fonctionnalité ajoutée, chaque bloc de code développé, la confusion grandira. Cela signifie que le projet meurt avec le temps. Vous avez peut-être beaucoup entendu : "Réécrivons ceci."
Tout d'abord, nous avons besoin de la sensibilisation de tous les membres de l'équipe et de l'institution propriétaire du projet. Parce que la réalisation d'un code propre coûtera du temps. (l'argent coûte naturellement, temps = argent)
Nous devons être motivés pour jumeler la programmation et le refactoring avec d'autres membres de l'équipe.
Nous devons communiquer davantage avec les équipes techniques et commerciales pour nous assurer que nous pouvons simplement expliquer et discuter du module ou du bloc de code.
Le codage propre n'est pas une compétence qui peut être acquise du jour au lendemain. C'est une habitude qui doit être développée en gardant ces principes à l'esprit et en les appliquant chaque fois que vous écrivez du code. Yigit Kemal Erinç
Cadre de code propre
Simple, ciblé, exhaustif, correct.
Afin que nous acceptions que les principes du code propre soient suivis ;
- Le code doit être simple et compréhensible.
- Les fonctions, les classes et les variables doivent être ciblées . Ils doivent être seuls responsables et ne pas avoir d'effets secondaires.
- Il doit pouvoir répondre à tous les besoins , couvrir les cas possibles, permettre l'évolution et prévenir les situations à éviter.
- Nous devons nous assurer qu'il fonctionne correctement . Cela n'est possible qu'avec des tests unitaires et d'acceptation. Des tests d'intégration sont nécessaires pour tester les intégrations.
Le nom d'une variable, d'une fonction ou d'une classe devrait répondre à toutes les grandes questions. Il devrait vous dire pourquoi il existe, ce qu'il fait et comment il est utilisé. Si un nom nécessite un commentaire, alors le nom ne révèle pas son intention. Robert C. Martin
public List<string> GetTags(int[] a)
{
var list = new List<string>();
for (var b = 0; b < theList.Count; b++)
{
if (theList[b].CityCodes.Intersect(a).Any())
{
list.Add(theList[b].TagName);
}
}
return list;
}
Sans un commentaire ou une plongée profonde dans le code, il m'est impossible de comprendre à quoi servent cette méthode et ces paramètres. À ce stade, si j'édite le nommage à condition que cela ait un sens dans le contexte dans lequel je développe, j'approche un code plus propre. Faisons-le.
public List<string> GetTagNamesThatMatchedCityCodes(int[] cityCodes)
{
var tagNamesThatMatchedCityCodes = new List<string>();
foreach (var tag in locationTags)
{
if (tag.CityCodes.Intersect(cityCodes).Any())
{
tagNamesThatMatchedCityCodes.Add(tag.TagName);
}
}
return tagNamesThatMatchedCityCodes;
}
Si l'on souhaite optimiser les performances notamment pour les grands ensembles de données, on peut également préférer l'utilisation du "rendement", mais cela risque de réduire la lisibilité du code. Dans de tels dilemmes, nous pouvons avoir besoin de décider si la lisibilité ou la performance du programme est importante pour nous. Par exemple, si je développe un algorithme de compression, je veux qu'il fonctionne efficacement. Mais si je développe un programme pour les entreprises et qu'il ne crée pas trop de charge système, je peux accepter de perdre un peu de performance pour avoir un code lisible et maintenable.
public IEnumerable<string> GetTagNamesThatMatchedCityCodes(int[] cityCodes)
{
foreach (var tag in tags)
{
if (tag.CityCodes.Intersect(cityCodes).Any())
{
yield return tag.TagName;
}
}
}
Développeur, analyste commercial, propriétaire de produit, etc. Les noms doivent être clairs et compréhensibles pour chaque membre de l'équipe. Eric Evans définit le concept de « langage ubiquitaire » dans son livre « Domain-Driven Design : Tackling Complexity in the Heart of Software », qui est un autre livre que je recommanderais de lire si vous en avez l'occasion.
Le langage omniprésent est l'un des éléments clés de la gestion de la complexité. Cette sensibilisation permettra également d'éviter les accidents du travail.
Fonctions courtes et ciblées
Nous devrions développer les fonctions aussi courtes et ciblées que possible. Ils ne doivent avoir qu'une seule mission (responsabilité unique) et ils doivent s'acquitter de cette mission au mieux de leurs capacités. Cette prise de conscience empêchera également la duplication de code.
Les méthodes comportant de nombreuses lignes de code augmentent la complexité. Surtout si nous avons une instruction if ou un bloc de code contenant des boucles, nous pouvons raccourcir le bloc de code en utilisant de nouvelles méthodes pour garder le code plus compréhensible. Il s'agit d'un sujet important dans les sessions de révision de code pour éviter une complexité accrue.
private void CreatePluralDependentMessageParts(int orderCount)
{
if (orderCount == 0) {
FormatMessageForCustomerWithNoOrder();
} else if (orderCount == 1) {
FormatMessageForCustomerWithSingleOrder();
} else {
FormatMessageForCustomerWithManyOrders(orderCount);
}
}
Les objets de transfert de données sont un moyen propre de transférer des données entre des couches ou des fonctions d'application.
Je peux parler d'un scénario qui vous arrivera probablement si vous n'utilisez pas d'objets de transfert de données. Comme dans l'exemple ci-dessous, le même type de paramètres de méthode revient dos à dos, le développeur essayant d'atteindre l'échéance peut confondre les paramètres de chaîne email et de chaîne appKey. Vous ne tarderez pas à vous rendre compte que votre service de notification par e-mail a échoué.
public Customer(string name, string surname, string email,
string appKey, int age, bool isPremium)
{
Name = name;
Surname = surname;
Email = email;
AppKey = appKey;
Age = age;
IsPremium = isPremium;
}
public Customer(CustomerDto customerDto)
{
Name = customerDto.Name;
Surname = customerDto.Surname;
Email = customerDto.Email;
AppKey = customerDto.AppKey;
Age = customerDto.Age;
IsPremium = customerDto.IsPremium;
}
Nous devrions éviter d'écrire des commentaires. À première vue, nous devrions être en mesure de comprendre à quoi sert le bloc de code. La dénomination correcte et la concentration sont très importantes pour la clarté.
Si le code n'est pas clair, nous devrions préférer la refactorisation du code plutôt que le commentaire. Cependant, des commentaires peuvent être faits pour des situations nécessitant une explication.
// Check to see if the order is eligible for shipping
if (order.Payment.IsCompleted && order.Delivery.Slot.IsAvailable)
if (order.IsEligibleForShipping())
Évitez d'utiliser des nombres magiques dans votre code. L'utilisation de constantes interrogeables vous aide à approcher un code plus propre. De plus, lorsque vous souhaitez apporter des modifications à votre logique métier, vous pourrez la modifier sans effort sans avoir à scanner l'intégralité du code.
if (password.Length > 10)
{
throw new ValidationException($"Must be at least 10 characters");
}
if (password.Length > MAX_PASSWORD_LENGTH)
{
throw new ValidationException($"Must be at least {MAX_PASSWORD_LENGTH} characters");
}
Parfois, nous pouvons constater que les blocs de code écrits pour traiter les résultats de validation ou gérer l'erreur augmentent trop et rendent le code difficile à lire. Il devrait y avoir une approche standard de la gestion des erreurs et de la validation dans toute l'application. Et nous devons nous assurer de ne pas polluer la base de code. Pour y parvenir, nous préférons peut-être lancer une exception plutôt que de porter des codes d'erreur ou des drapeaux. Nous pouvons développer un middleware de gestion des erreurs pour enregistrer les exceptions et formater notre réponse.
public bool IsValidPassword(string password)
{
if (string.IsNullOrEmpty(password))
throw new ValidationException("Cannot be null or empty");
if (password.Any(char.IsLetterOrDigit))
throw new ValidationException("Must contain at least one special character");
if (password.Length > MAX_PASSWORD_LENGTH)
throw new ValidationException($"Must be at least {MAX_PASSWORD_LENGTH} characters");
return true;
}
Pour notre santé mentale et celle de notre équipe, nous devrions essayer d'améliorer notre code en évitant les développements irréguliers. Un code sale causera plus de temps perdu à l'avenir et pire, des problèmes très difficiles à résoudre. En vous en tenant aux principes du code propre, vous vous rendrez compte que vous développez un code de meilleure qualité, et les résultats de vos développements vous procureront plus de bonheur.
Merci pour votre temps.
Okan Yüksel, ingénieur logiciel
Les références
- Robert C. Martin, 'Clean Code: Un manuel d'artisanat logiciel agile'
- Akın Kaldıroğlu, Code propre
- Yiğit Kemal Erinç,https://www.freecodecamp.org/news/clean-coding-for-beginners/
- Sultan ensoleillé,https://sunnysultan1640.medium.com/what-is-bad-code-how-to-write-clean-code-a9b7b539ad8
![Qu'est-ce qu'une liste liée, de toute façon? [Partie 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































