Conception : comment faire ?
  • une infinité de manière ;
  • choiser la plus adéquate aux besoins et moyens, actuels et futurs.
Architecture : structure du projet.
  • impacte fortement l'écriture, la compréhension, le débogage, l'extension, le maintenance, etc.
  • coût de la conception rapidement rentabilisé en rapidité et confort par la suite.
Dette technique : coût d'un choix passé, souvent d'autant plus coûteux que le projet est avancé.
  • e.g. composants interdépendant complexifient les modifications jusqu'à casser l'intégralité du projet.
D'autres se sont plantés avant nous, ont appris de leurs erreurs, et ont partagé leur expérience :
KISS : Keep it Simple, Stupide, restez simple. Appliquez ces principes avec raison sans vous perdez dedans.
Programmation Orientée Composant (POC) : découper son projet en plusieurs composants.
  • transforme un problème complexe en sous-problèmes plus simples à résoudre.
  • indépendance : pour les développer, tester, déboguer, etc. sans se soucier des autres.
  • substituabilité : possibilité de remplacer un composant par un autre (e.g. nouvelle version).
  • limite la portée des modifications : casser un composant ne casse pas les autres.
Découpage "horizontal" : composants "côtes à côtes", e.g. données et affichage :
  • l'affichage est indépendante de la manière dont sont stockées les données.
  • les données sont indépendantes de la manière dont elles sont affichées.
  • Idéalement l'un n'a pas besoin de l'autre pour s'exécuter,
    • API REST
    • changer la source de données (e.g. simulée)
Une pléthore de découpages possibles, typiquement affichage, données, comportements/règles avec quelques variations, e.g. : MVC, MVA, MVP, MVVM, PAC, ADR, modèle de Seeheim, architecture 3-tiers, etc.
Autre découpage possible : en fonction des fonctionnalités, e.g. gestion des utilisateurs/produits/tâches.
  • permet d'ajouter ou retirer des fonctionalités aisément sans impacter l'ensemble du projet.
💡 Ces différents découpages ne sont pas exclusifs.
💡 Un composant peut être redécoupé, e.g. l'affichage en structure, mise en forme, interactions.
Découpage "vertical" : un composant utilise (et est dépendant) d'un autre.
  • e.g. l'affichage dépendant d'un composant graphique (e.g. bibliothèque graphique).
    • changer l'implémentation du composant graphique n'impacte pas l'affichage.
    • mais l'affichage ne peut s'exécuter sans le composant.
Principe d'encapsulation : le composant est vu comme une boîte noire, son utilisateur n'a pas besoin d'en connaître le fonctionnement interne.
💡 Pas toujours vrai : nécessité de comprendre le fonctionnement général de Git/SQL pour bien les utiliser.
Abstraction : grâce à l'encapsulation, permet des opérations en cachant les détails techniques, e.g. :
  • : cache les vérifications et opérations effectuées par l'OS et le FS.
Couches d'abstraction (découpage vertical) :
  • les détails techniques sont encapsulés par les couches les plus basses.
  • les couches les plus hautes peuvent être une traduction du cahier des charges
    • réutilise la logique et le langage métier.
    • le client peut comprendre et modifier le code.
  • DP Façade : cache un ensemble de classes et d'opérations complexes derrière une interface unique.
  • DP Iterator : permet le parcours d'une structure indépendamment de son implémentation :
    • écrire des algorithmes génériques.
    • différents types de parcours possibles.
    • Utilisé en interne par et .
  • DAO (Data Access Object) : encapsule l'accès à des données persistantes.
    • e.g. ,
    • les méthodes effectuent les opérations via, e.g. des requêtes SQL, des commandes Shell, etc.
Découpage "éclaté" : découper le projet en fonctionnalités, chacune "éclatée" dans divers services.
  • services : composants de l'architecture générale (e.g. GUI, API REST, Database, etc.).
  • package : lot de composants correspondant à une fonctionnalité.
  • le contenu de chaque package est déployé dans les différents services afin de les étendre.
Diagramme de déploiement : décrit les composants ainsi que les matériels sur lesquels ils sont déployés.
💡 Il est possible de préciser les caractéristiques (e.g. mémoire, processeur, etc.) des matériels.
💡 Il existe aussi des diagrammes de composants et des diagrammes de package.
  • Les composants communiquent entre eux.
    • différents types de messages (e.g. appel de fonction, requête REST, etc.).
    • un composant doit comprendre les messages qu'il reçoit ("parler la même langue").
    • spécifier un protocole de communication ≈ contrat (e.g. API REST, interface, etc.).
  • Le composant doit être une boîte noire pour l'extérieur (cf encapsulation) :
    • pas d'accès à ses éléments internes.
    • interactions uniquement par le biais d'une interface (e.g. via DP façade).
Architecture monolithique : tout dans un même exécutable.
  • Message = appels de fonctions (généralement).
    • Synchrone : j'attends la réponse.
    • Asynchrone : je n'attends pas la réponse.
Pour éviter certains problèmes, on distingue souvent l'enclenchement de l'action et son traitement :
  • : j'enclenche l'action.
  • : je traites l'action.
examples (appel extérieur boucle infinie e.g. remove + inherit do not forget some operations - DP Template)
Service Oriented Architecture (SOA) : différents exécutables fournissant des services différents.
  • appels de fonctions impossibles entre exécutables.
  • on utilise alors des communications inter-processus (IPC) :
    • Fichiers FIFO : pipes, sockets.
    • Événements : message queue, signaux unix.
    • Données : sémaphores, mémoire partagée.
Ne peut transmettre que des données binaires (e.g. JSON), nécessité de :
  • Envoi : sérialiser le message.
  • Réception : désérialiser le message.
Micro-services : les services sont sur des serveurs différents.
  • communications par le biais de sockets.
  • nécessité d'un protocole de communication (e.g. API REST).
  • ⚠ Coût élevé des communications, bien plus qu'un simple appel de fonction.
Event-Driven Architecture (EDA) : abstrait des méthodes de communications précédentes.
  • une source d'événement diffuse (broadcast) des événements ;
  • les fonctions abonnées (subscribed) à cet événement sont appelées.
  • DP Observer : la source stocke et appelle elle-même les fonctions abonnées.
  • DP Reactor : une boucle d'événements appelle les fonctions abonnées (e.g. JS, serveurs, etc.).
💡 En fonction du contexte, la fonction abonnée peut être appelée listener ou handler.
Cf aussi : programmation réactive.
X
  • Interceptor DP
  • Adapter
  • Proxy : log, cache, etc.
  • Mediator DP
  • Broker : load balancing, redirect, etc.
  • DP Commande : e.g. associer GUI btn à une action controler.
  • Data Transfert Object : regrouper plusieurs requêtes avant d'envoyer
  • Message queuing
  • Chaîne de responsabilité : pour les handler, un seul s'en occupe.
Diagramme de séquence : dans le cadre d'un scénario donné, montre les interactions entre divers entités.
Ref + Alt + opt (p 635 ) + loop + par (parallel).
Diagramme de communication : ≈ séquence. Lorsqu'il y a trop d'entités et peu de messages.
- Global d'interaction (en gros un diagramme d'activité dont les noeuds sont d'autres diagrammes). - Temps.