Aller au contenu principal

Architecture front

De manière générale :

  • Diviser l'appli en couches, séparer domaine / infrastructure / UI
  • Eviter le code métier dans un composant d'UI (le sortir dans un controller/service séparé) => meilleur découpage et permet de tester unitairement plus facilement (vu que pas besoin de gérer le framework d'UI)
  • Eviter l'import de store, services,... dans le fichier du controller directement ! Venir l'injecter dans le constructeur => permet de pouvoir mocker lors du test unitaire (cf dependency-cruiser qui permet de mettre des règles de dépendances, et les visualiser)
  • Penser au SRP => Single Responsibility Principle
  • Eviter de coupler du code qui va diverger avec le temps : il vaut mieux parfois un code découplé qu'un code DRY
  • Forte cohésion et faible couplage !

Gestion des dépendances​

  • Les dépendances du code source doivent pointer vers l'intérieur => plus facile d'isoler l'impact de nos changements
  • Plusieurs façons d'organiser nos dépendances
    • Ne pas les organiser (= un beau bordel)
    • En couche (Couche A et E dépendant de couche B, B dépendant de couche C etc)
    • Par module
  • Inconvénients d'une mauvaise gestion : risque fort (ou inconnu) de régression
  • Avantages d'une bonne gestion : limite le scope de régression. N'affecte pas les autres équipes.

Couplage​

  • = dépendances entre modules
  • Dépendance = nécessaire au bon fonctionnement du module
  • Plusieurs types de couplages : appel de méthodes, héritage, paramètre de méthode,...
  • Impacts : modification en cascade, réutilisation + difficile, tests et externalisation + difficile
  • Couplage efférent vs afférent
    • Efférent = dépendance sortante, le nb de classes dans un paquet qui dépendent d'une classe d'un autre paquet
    • Afférent = dépendance entrante, le nb de classes hors d'un paquet qui dépendent des classes dans le paquet
  • Minimiser le couplage !

Quelques métriques utilisées : (de part les travaux du LCOM4 - Lack of Cohesion in Methods)

  • CBO (Coupling Between Objects) = couplage entre objets, nb de classes couplées à la classe mesurée
  • LCOM (Lack of Cohesion of Methods) = mesure le manque de cohésion de la classe
  • LCC (Loose Class Cohesion) = le nombre relatif de méthodes connectées directement
  • TCC (Tight Class Cohesion) = le nombre relatif de méthodes connectées directement et indirectement
  • MCC (McCabe's Cydomalic Complexity) = le nombre de chemins possibles à l'intérieur d une méthode

Cohésion​

  • = niveau d’appartenance entre éléments d’un même module, lien entre les éléments d’un même module
  • Différents types de cohésions
    • coincidence (= accidentelle, aléatoire)
    • logique (regroupement par type d’opération, exemple "controllers")
    • temporel (regroupé par activitées liées dans le temps)
    • procédural
    • communicationnel/Informationnel (regroupement par opération sur les mêmes données (ex: utils) )
    • séquentiel
    • fonctionnel (regroupement par cas d’utilisations)

Architecture hexagonale​

Aussi appelé "ports et adapters", "port" étant l'interface que le code doit implémenté pour s'abstraire d'une technologie, et "adapter" étant l'implémentation de cette interface.

  • Couche Domain
    • Interface (typage métier) => de la donnée métier ("Entities" ou "Models") et du controller
    • Usecase (= besoin fonctionnel de l'application)
      • Exemple : "Un panier ne peut pas contenir plus de 10 produits" ou "Ajouter un article au panier"
      • C'est l'orchestrateur
  • Couche Infrastructure
    • gestion des appels vers le back
    • services,...
    • DTO (Data Transfer Object) : interface/typage de la donnée qui nous est retournée par le back
  • Couche UI : composants d'UI => ne doit pas contenir de code métier, interagit avec la couche infrastructure

Architecture hexagonale

Clean architecture​

  • Principes
    • Indépendant des frameworks (frameworks de vue, de gestion du réseau, de la BDD, etc)
    • Découpage métier : pas de regroupement technique (par dossier “services”, “controller”, etc) mais un regroupement métier par module
    • Création de usecase / interactor (un usecase = une fonctionnalité métier)
  • Avantages
    • Simplifie le changement d’implémentation
    • Implémentation des fonctionnalités plus rapide
    • Réutilisation des usecases
  • Risques : trouver le juste milieu en trop / pas assez découper

Onion architecture​

SOLID​

= 5 principes de conception pour une bonne architecture

Principes inventés par Robert C Martin (livre "Design Principles and Design Patterns") et acronyme créé par Michael Feathers.

  • Single responsibility = une classe ne doit comporter qu'une seule responsabilité, "une classe ne doit avoir qu'une seule et unique raison de changer"
  • Open/closed
  • Liskov substitution
  • Interface segregation = un client ne doit pas être forcé à dépendre d'interfaces qu'il n'utilise pas, il faudrait ne voir que les services qu'il utilise réellement !
  • Dependency inversion

Sources​