SOLID : guide pour débutant en Java (Partie 1)

L'objectif n'est pas de mémoriser ces principes par cœur, mais de les comprendre pour pouvoir les appliquer efficacement dans les principes SOLID

Cette note a pour objectif de partager mon expérience sur les 5 principes SOLID et vous montrer comment les utiliser au quotidien en tant que développeur grâce à des exemples applicables.

SOLID dans l'univers des Devs, c’est quelque chose dont on entend souvent nos mentors nous parler. Nos mentors nous disent souvant : si tu veux être un bon dévéloppeur il faut comprendre et appliquer les principes SOLID.

Mais est-ce vraiment le cas ? ( Je vous laisse repondre à cette question de vous même à la fin de la lecture)

Qu'est ce que SOLID ?

L'acronyme S.O.L.I.D. a été introduit par Robert C. Martin, également connu sous le nom d'Oncle Bob . Ces principes sont basés sur des concepts de programmation orientée objet et visent à améliorer la lisibilité, la facilité de maintenance, l'extensibilité, la réutilisabilité et à éviter les redondances dans le code.

SOLID, c’est un acronyme pour ces 5 principes de programmation.

  1. S : Single Responsibility Principle

  2. O : Open/Closed Principle

  3. L : Liskov’s Substitution Principle

  4. I : Interface Segregation Principle

  5. D : Dependency Inversion Principle

L'objectif n'est pas de mémoriser ces informations par cœur, mais de les saisir suffisamment afin de les appliquer correctement lorsque nécessaire.(Désolé pour ceux qui cherchent à retenir par coeur toutes les balises HTML)

Pourquoi faire du code SOLID ?

Comprendre en profondeur SOLID et l'appliquer dans votre travail quotidien présente deux avantages majeurs :

Tout d'abord, cela vous permet d'améliorer la qualité de votre code. En intégrant les principes SOLID, vous adoptez une approche plus structurée et modulaire pour la conception logicielle. Résultat : un code mieux organisé, plus lisible et plus facile à entretenir. Les futurs changements et améliorations peuvent être réalisés avec moins d'efforts et de risques d'effets indésirables.

Ensuite, la maîtrise de SOLID vous donne les clés pour comprendre des codes plus complexes, comme ceux présents dans des frameworks ou des projets avancés. Ces codes sont généralement conçus selon des normes de conception rigoureuses pour assurer performance, stabilité et sécurité. En assimilant les principes SOLID, vous pouvez décrypter ces codes sophistiqués, identifier leurs structures et leurs modèles, voire contribuer plus efficacement à leur amélioration.

En résumé, la compréhension et l'application régulière de SOLID rehausseront la qualité de votre propre code et faciliteront votre navigation au sein de projets logiciels avancés. Cela renforcera considérablement vos compétences en tant que développeur.

Comment utiliser SOLID dans son code JAVA (avec exemples concrets) ?

Un des principaux obstacles à l'adoption des principes SOLID réside dans la perception répandue selon laquelle cela semble complexe et réservé aux développeurs exceptionnels.

S : Single Responsibility Principle (SRP)

Une erreur fréquente dans de nombreux projets est d'avoir une classe comme UserService.java qui contient un mélange de fonctionnalités diverses et variées pour la gestion des utilisateurs par exemple.

De plus, le nom UserService.java n'est pas du tout descriptif, ce qui ne permet pas de comprendre le contenu du fichier dès le premier regard.

Voici un exemple de code qui ne suit pas le principe de responsabilité unique (SRP)

package org.example;

/**
 * UserService
 * Author : @tchirktema
 */
public class UserService {
    public User createUser(User user){
        /**
         * Implementation de la creation d'un utilisateur
         */
        return null;
    }
    public User updateUser(User user,String userId){
        /**
         * Implementation de la mise à jour d'un utilisateur
         */
        return null;
    }
    public User deleteUser(String userId){
        /**
         * Implementation de la suppression d'un utilisateur
         */
        return null;
    }
    public User blockUser(String userId){
        /**
         * Implementation du blockage d'un utilisateur
         */
        return null;
    }
}

Nous voyons que cette class UserService.php permet de gérer plusieurs tâches à la fois à savoir :

  1. La création des utilisateurs

  2. La mise à jour des utilisateurs

  3. La suppression des utilisateurs

  4. Bloquer les utilisateurs

Voici un exemple de code qui suit le principe de responsabilité unique (SRP)

Au lieu d'avoir un seul fichier nous avons nous retrouver avec une arborescence suivantes:

Services/
└── User
    ├── UserCreationService.java
    ├── UserUpdateService.java
    ├── UserBlockService.java
    └── UserDeleteService.java
    ├── ...

UserCreateService.java

package org.example.services.user;

import org.example.User;

public class UserCreationService {
    public User createUser(User user){
        /**
         * Implementation de la creation d'un utilisateur
         */
        return null;
    }
}

UserUpdateService.java

package org.example.services.user;

import org.example.User;

public class UserUpdateService {
    public User updateUser(User user){
        /**
         * Implementation de la creation d'un utilisateur
         */
        return null;
    }
}

UserBlockService.java

package org.example.services.user;

import org.example.User;

public class UserBlockService {
    public User blockUser(User user){
        /**
         * Implementation de la creation d'un utilisateur
         */
        return null;
    }
}

UserDeleteService.java

package org.example.services.user;

import org.example.User;

public class UserDeleteService {
    public User deleteUser(User user){
        /**
         * Implementation de la creation d'un utilisateur
         */
        return null;
    }

⭐️ Il est important d'appliquer le principe de responsabilité unique (SRP) pour plusieurs raisons :

Clarté du Code: Diviser une classe de 1000 lignes en classes plus petites rend le code beaucoup plus lisible et compréhensible. Chaque classe ne se concentre que sur une seule responsabilité, ce qui simplifie la lecture et la maintenance.

Cohérence des Rôles : Chaque fichier a maintenant un rôle spécifique et défini. Cela facilite la compréhension du rôle de chaque classe, ce qui est d'autant plus utile lors de la collaboration au sein d'une équipe de développement.

Facilité de Maintenance : En respectant le SRP, les modifications à apporter sont isolées dans des classes spécifiques. Cela réduit les risques d'effets secondaires indésirables lors de la modification d'une fonctionnalité, ce qui rend la maintenance plus sûre et plus rapide.

Évolutivité : La conception modulaire basée sur le SRP rend le projet plus adaptable. L'ajout de nouvelles fonctionnalités ou la modification de celles existantes est plus simple, car vous pouvez vous concentrer sur une seule action à la fois.

Vocabulaire Explicite : En nommant les classes en fonction de leur responsabilité, comme dans le dossier "Services/User", le code devient un moyen de documentation. Les noms explicites aident les développeurs à comprendre rapidement le but de chaque classe.

Productivité : En se concentrant sur une seule action par classe, les développeurs peuvent travailler plus efficacement. La conception modulaire leur permet de coder plus rapidement et avec moins d'ambiguïté.

En résumé, l'application du principe SRP conduit à un code plus lisible, maintenable, évolutif et efficace. Cela facilite la collaboration au sein de l'équipe et contribue à la qualité globale du projet.

Partie 2 (Disponible très bientôt)