=====3 types d'architecture==== ====Architecture fonctionnelle==== Cela consiste à décrire les besoins d'un point de vue exclusivement métier sans aborder la partie technique du logiciel. On peut déjà imaginer les briques logicielles avec leurs fonctions et leurs interactions mais toujours exclusivement du point de vue métier. ====Architecture logicielle==== ===Structure=== Un logiciel est composé de sous-systèmes (facultatif), eux-mêmes composés de composants logiciels. Un composant peut être : * un logiciel développé spécifiquement durant le projet de développement; * un logiciel réutilisé depuis un autre projet, * un progiciel sur étagère que l’on intègre, * un logiciel dont on utilise simplement les services mais qui reste extérieur au système, * un ou plusieurs fichiers / bases de données. Un composant possède : * un aspect visible (interface), * des fonctionnalités, * des propriétés (ou contraintes ou exigences non fonctionnelles). Cela peut-être la volumétrie de la base de données, les besoins en bande passante, le délai maximum en temps d'exécution d'une fonction. {{ :helloworld:architecture:notion:structure_logiciel.svg |}} ===Aspects dynamiques=== * Global : scénarios d'exécution, coopération entre composants (ordre d'exécution des constituants, constituants en parallèle), * Constituant : contrainte d'exécution (parallélisation autorisée des fonctions, imposer un ordre d'exécution des fonctions). ===Déploiement=== Spécifier les contraintes de déploiement et la description de l'infrastructure : machine, OS, plateforme (java, ...) ====Architecture système==== L'architecture logicielle est la partie de l'architecture système qui détaille la description des éléments applicatifs. Une architecture système regroupe : * l'architecture logicielle : liste des composants à développer avec leurs interfaces (de programmation), * l'architecture technique : choix du langage de programmation et des briques logiciels (par exemple : quelle librairie gérera la persistance des données), * l'architecture physique : ordinateur ou tablette ? Choix des OS supportés ? {{ :helloworld:architecture:notion:architecture_systeme.svg |Architecture système}} =====Composition d'une architecture===== ====Composant==== Les composants sont visibles des autres composants exclusivement à travers des interfaces. ===Dépendances entre composants=== * service : pour obtenir un service ou une information, * réalisation : implémentation par héritage, * manifestation : nécessite un artefact pour s'exécuter / s'implémenter. ===Rôles=== Il est préférable mais pas obligatoire qu'un composant ne supporte qu'un rôle à la fois, sauf pour les deux premiers qui sont les fondamentaux de la programmation orientée objet et le troisième qui gère les besoins en concurrence. * Stocker des données (composant de type Entité), * Fournir des traitements (composant de type Service), * Contrôle interne (composent de type Contrôleur) : aucun, exécution possible en concurrence par file d'attente ou vraiment en parallèle, vérification des paramètres, * Maintenir un contexte : gérer des informations de sessions, garder un fichier ouvert, système de cache, * Interface graphique, * Gestion d'un matériel physique, * [[helloworld:design_pattern:proxy|Proxy]], * [[helloworld:design_pattern:fabrique_abstraite|Machine abstraite]]. ===Enchaînement=== Il y a plusieurs façons d'enchaîner l'exécution de composants de type traitement : * Procédurale : deux lignes de code qui se suivent. Inconvénient : plus difficilement réutilisable dans un autre environnement / projet, * Événement : A signale à B qu'il a terminé et que B peut commencer ([[helloworld:design_pattern:publish_subscribe|publisher/subscriber]], [[helloworld:design_pattern:command|commander]]?) * Données : quand A a terminé, il envoie les résultats à un buffer tampon que, soit B va consulter régulièrement, soit le buffet va contacter B directement. ====Interface==== Une interface est attachée à un port de communication du composant. Il existe deux types d'interface : le cercle représente l'interface offerte (les différentes méthodes à disposition) et le demi cercle l'interface requise (le prototype des méthodes doit correspondre à l'interface offerte). ====Port==== Une interface est attachée à un port du composant, noté par un carré. Cela peut être l'exécution de la méthode en local ou via une API distante ou la possibilité d'avoir les deux à la fois. ====Connecteur==== Les composants interagissent donc sur des ports, par le biais de connecteurs, et via des interfaces. Ils fournissent des services de : * Communication : appel local ou distante, * Coordination : * appel synchrone : on attend le retour, * événement simple : on envoie un évènement, on attend pas le retour. Si le destinataire n'est pas prêt à recevoir le message, il est perdu, * événement bufferisé : idem qu'un événement simple sauf que le destinataire stocke le message en attente s'il n'est pas prêt à le traiter tout de suite, * flots de données : envoie de données en continu peu importe si le destinataire manque quelques messages, * Appel asynchrone : A envoie la demande à B, le retour arrivera plus tard de B vers A, * Pub/Sub : A envoie un message à B avec un <>, le retour arrivera à tous les composants qui se sont inscrites au <>, * Conversion de données entre les deux ports, * Facilitation : régulation de charge, appel concurrent ====Artefact==== La manifestation concrète d’un composant est appelée artefact. C’est une instance concrète du composant déployée dans l’environnement d’exécution. Voir [[helloworld:architecture:uml#|UML]] ====Kruchten : 4+1 vues==== ^Vue^Description^Diagrammes^ |Logique|Composants présents et leurs interactions| Paquetages, classes, objets et structures (UML), blocs (SysML)| |Réalisation|Organisation des composants concrets sur une plateforme.|Composants, paquetages, structures composites.| |Processus|Allocations et interactions entre processus, threads ou tâches.|Activités, séquence, communication, états-transitions.| |Déploiement|Environnement d'exécution y compris contraintes géographiques, de bandes passants et de performances du système.|Composants, déploiement.| |Cas d'utilisation|Scénarios correspondant à une fonctionnalité du système s'activant depuis une interaction extérieure.|Cas d'utilisation, activités, séquence, communication, états-transitions.| {{ :helloworld:architecture:kruchten:interaction_vues.png |}} {{ :helloworld:architecture:kruchten:interaction_architecture.png |}} =====Qualité===== ====Généralités===== * Interfaces simples, claires, stables et complètes, * Dépendances faibles entre les constituants, * Complexité interne masquée par les interfaces, * Modularité, * Facilité d’intégration, * Durée de vie, upgradablité (remplacement d’une technologie par une autre). ====Couplage==== Le couplage reprendre le niveau d'interaction entre les composants logiciels. Selon Pressman, 7 niveaux de couplage, classé par niveau de dépendances, le meilleur est le premier : ^Couplage^Description^ |Sans couplage|Les composants n'échangent pas d'information.| |Par données|Les composants échangent de l'information par des méthodes utilisant des arguments de type simple (entiers, réels, chaînes de caractères, etc.). Compatible entre les différents languages de programmation.| |Par paquet|Les composants échangent de l'information par des méthodes utilisant des arguments de type composé (structure, classe). Nécessite des changements si le language de programmation change d'un coté.| |Par contrôle|Les composants se passent ou modifient leur contrôle par modification d'un drapeau interne au composant invoqué (verrou).| |Externe|Les composants échangent de l'information par un moyen de communication externe (par exemple fichier, queue de message, variable d’environnement, etc.)| |Commun (global)|Les composants échangent de l'information via un ensemble de données communes| |Par contenu (interne)|Les composants échangent de l'information en lisant et écrivant directement dans leurs espaces de données respectifs.| ====Cohésion==== La cohésion est une mesure d'homogénéité dans un composant ou un sous système. Selon Pressman, 7 niveaux de cohésion, classé par niveau, le meilleur est le dernier : ^Cohésion^Description^ |Arbitraire|Absence de lien logique entre les éléments.| |Logique|Les fonctions sont de même catégorie ou reliées par un ou plusieurs critères communs.| |Temporelle|Les fonctions s’exécutent dans une même période de temps.| |Procédurale|Les fonctions sont appelées selon une séquence bien déterminée (et non arbitrairement au gré de l’appelant).| |Communicationnelle|Les fonctions ont les mêmes types d’entrées sorties.| |Séquentielle|Les opérations forment des séquences d’exécution bien identifiées (la sortie de l’une est l’entrée de l’autre).| |Fonctionnelle|Les fonctions contribuent à une même fonction de plus haut niveau, ou bien relèvent d’une abstraction commune.| =====Styles===== Les styles architecturaux et les pattern design sont proches. Les pattern s'appliquent à un composant précis alors que les styles s'appliquent à un sous système entier. Principaux styles de base: ===Architectures hiérarchique et orientée objets=== Arborescence en arbre avec à la racine le main. Chaque descendant sont un sous-module. {{:helloworld:architecture:style:fig1_3.png|}} [[https://laurent-audibert.developpez.com/Cours-UML/?page=introduction-modelisation-objet|UML 2 - De l'apprentissage à la pratique]] {{ :helloworld:architecture:uml:uml2-apprentissage-pratique.pdf |Archive du 12/01/2009 le 28/04/2020}} ===Architecture à flot de données (pipe-line)=== Exemples : [[helloworld:design_pattern:chain_of_responsibility|Chaîne de responsabilité]] {{:helloworld:architecture:style:pipeline.png|}} [[http://parc.sourceforge.net/intro.html|Pipeline Architecture - Introduction]] {{ :helloworld:architecture:notion:pipeline_architecture_-_introduction_2020-04-28_11_07_03_pm_.html |Archive du 06/01/2004 le 28/04/2020}} ===Architecture avec référentiel de données (repository centric), Architecture Tableau noir (blackboard)=== Il y a les composants accesseurs de données d’une part, qui implémentent les traitements, et les composants « référentiels de données » d’autre part, qui maintiennent des données écrites et lues par les premiers. Dans la version de base, les référentiels sont passifs (vocation de stockage). Dans la version tableau noir, les référentiels informent les accesseurs des modifications ([[helloworld:design_pattern:observer:java|observer]]) {{:helloworld:architecture:style:cycleenv2.png|}} [[http://www.case-france.com/EnvisionArchitectureSysteme.html|Architecture système]] {{ :helloworld:architecture:notion:envision_system_architecture_2020-04-28_11_07_03_pm_.html |Archive du 2016 le 28/04/2020}} ===Architecture à Invocation implicite=== Voir [[helloworld:design_pattern:publish_subscribe|pub/sub]], [[helloworld:design_pattern:reactor|reactor]] ===Architecture multi-couches=== Chaque couche a accès uniquement à sa (ou des) couches inférieures. ===Architecture distribuée, spécialisée en architectures N - tiers=== Ici, chaque couche n'a accès qu'au niveau N+1 et N-1.