ARCHITECTURE LOGICIELLE
N’TAKPE N’guessan Christian
Université Virtuelle de Côte d’Ivoire
May 29, 2024
1 / 56
2 / 56
Plan
Introduction à l’architecture logicielle
Principes fondamentaux
Styles et modèles architecturaux
Outils et techniques de modélisation
3 / 56
Introduction
Définition
L’architecture logicielle d’un système est l’ensemble des structures
nécessaires pour raisonner sur le système. Ces structures comprennent
les éléments logiciels, les relations entre eux et les propriétés de chacun
Système ?
Structure ?? Une structure est simplement un ensemble d’éléments reliés
entre eux. Les systèmes logiciels sont composés de nombreuses
structures. Une structure est architecturale si elle permet de raisonner sur
le système et ses propriétés.
Structures de composants et connecteurs
Structures de modules
Structures d’allocation
4 / 56
Introduction
Définition
L’architecture d’un programme ou d’un système informatique est la
structure (ou les structures) du système qui comprend les éléments
logiciels, leurs propriétés visibles et leur relations
L’architecture d’un système est sa conception de haut niveau
N’importe quel système complexe est composé de sous-systèmes
(structure) qui interagissent entre eux
La conception de haut niveau est le processus qui consiste à identifier ces
sous-systèmes ainsi que les relations qu’ils entretiennent entre eux.
L’architecture d’un système est le résultat de ce processus
Il n’y a pas une architecture unique permettant de réaliser le système, il y
en a plusieurs.
5 / 56
Introduction
Architecture VS conception
Architecture :
Ainsi, une architecture est avant tout une abstraction d’un système
qui sélectionne certains détails et en supprime d’autres.
Architecture Logicielle et intrinsèque à tout logicielle
Pont entre les objectifs commerciaux abstraits et le système concret.
Le comportement des éléments incarne comment ils interagissent
entre eux et avec l’environnement
Ex. dans yango: conducteur, passager, trajet, réservation, etc.
La conception (design):
Détails d’implémentation réelles (IHM, stockage, accès, sécurité,
fréquence/débits,performances)
Premiers livrables de code
est une conception, mais toute conception n’est pas architecturale
6 / 56
Introduction
Pourquoi l’architecture logiciel??
Pourquoi l’architecture logiciel??
Maı̂triser la complexité du système
Vision globale, modèle structuré, hiérarchique
Servir de racine commune pour :
Conception détaillée et implantation
Estimation des coûts et gestion de projet
Analyses et validation
Évolutions
Support pour la ré-utilisabilité des systèmes logiciels
Vision globale, modèle structuré, hiérarchique
Formaliser les choses de façon générique. Toujours anticiper leur
possible évolution.
Conception d’architecture = définir un logiciel facile à faire évoluer
7 / 56
Introduction
Exemple simpliste
Exemple : décrire l’architecture logicielle d’un système constitué de
deux clients et un serveur.
8 / 56
Introduction
Exemple
Structure explicite
Notion de composant, dotés d’interface, interconnectés
Compréhension intuitive
Serveur mono ou multi-thread ?
Activation des composants ?
9 / 56
Représentation des architectures
Représentation des architectures
Peuvent être regroupés en trois grandes familles en fonction de leurs
Structures
Structures de composants et connecteurs
Structures de modules
Structures d’allocation
Une des représentations les plus utilisées est la représentation :
Composants et Connecteurs
10 / 56
Représentation des architectures
Structures de Modules
Focus : Divisent les systèmes en unités de mise en œuvre
appelées modules.
Modules
Comprennent classes, packages, couches, et divisions de
fonctionnalités.
Représentent une manière statique de considérer le système.
Relations entre Modules
Incluent les relations d’utilisation, de généralisation (ou ”est-un”),
et ”fait partie de”.
Utilisent la notation UML pour décrire ces relations
11 / 56
Représentation des architectures
Structures de Modules
Focus : Divisent les systèmes en unités de mise en œuvre
appelées modules.
Questions abordées :
Quelle est la responsabilité fonctionnelle principale assignée à
chaque module ?
Quels autres éléments logiciels un module est-il autorisé à utiliser ?
Quels autres logiciels utilise-t-il réellement et sur lesquels dépend-il
?
Quels modules sont liés à d’autres modules par des relations de
généralisation ou de spécialisation (héritage) ?
raisonnement:
Outils principaux pour raisonner sur la modifiabilité d’un système.
Utilisés pour évaluer l’impact des changements de responsabilités
des modules.
12 / 56
Représentation des architectures
Exemple structure module
13 / 56
Représentation des architectures
Structures allocation
Focus : établissent la correspondance entre les
structures logicielles et les structures non logicielles du
système, telles que son organisation, ou ses
environnements de développement, de test et
d’exécution
Raisonnement
Sur quel(s) processeur(s) chaque élément logiciel s’exécute-t-il ?
Dans quels répertoires ou fichiers chaque élément est-il stocké
pendant le développement, les tests et la construction du système ?
Quelle est l’affectation de chaque élément logiciel aux équipes de
développement ?
14 / 56
Représentation des architectures
Structures de composants et connecteurs
Focus : Interaction des éléments pendant l’exécution
pour réaliser les fonctions du système
Description
Composants : Unités de calcul (services, pairs, clients, serveurs,
filtres, etc.).
Connecteurs : Moyens de communication (appels-retours,
synchronisation de processus, pipelines, etc.).
Questions abordées :
Principaux composants en cours d’exécution et leurs interactions.
Progression des données à travers le système.
Parties du système pouvant fonctionner en parallèle.
Changement de structure du système pendant l’exécution.
raisonnement:
Pose des questions sur les propriétés à l’exécution du système
(performance, sécurité, disponibilité, etc.). 15 / 56
Représentation des architectures
Exemple architecture composant-connecteur
16 / 56
Architecture composant-connecteur: Composant
Définition d’un composant ?
Un composant est un module logiciel répondant à un besoin fonctionnel
ou applicatif ( (application, bibliothèque, module, . . . etc.) ou un entrepôt
de données)
Un composant est identifié par son nom, qui indique son rôle dans le
système.
Les composants communique entre eux en utilisant des ports (ou
interfaces)
Les architectures utilisent des composants standards : serveurs, bases de
données, application, clients, . . . etc.
17 / 56
Architecture composant-connecteur: Composant
serveur et client?
Un serveur est un module logiciel qui répond aux requêtes d’autres
modules appelés clients
Généralement, les services et les clients sont hébergés dans des machines
différentes et communiquent via le réseau (intranet / internet)
Les composants communique entre eux en utilisant des ports (ou
interfaces)
Par exemple, le service http répond aux requêtes des clients qui sont les
navigateurs web
18 / 56
Architecture composant-connecteur: Application
Application ?
Une application est un module logiciel qui a un rôle défini dans le
système logiciels
Par exemple, une application d’envoi de mails
19 / 56
Architecture composant-connecteur: Base de données
Base de données ?
Une base de données est un entrepôt stockant les données sous un format
normalisé
L’interrogation et la modification des données se fait en utilisant un
langage spécial appelé SQL
La plupart des bases de données obéissent au modèle relationnel
Un SGBD (Système de Gestion de Base de Données) est une base de
données puissante et accessible sur le réseau conçue généralement pour
les gros systèmes
SQL Server, Oracle, MySQL sont des exemples de SGBD connus sur le
marché
20 / 56
Vue de l’architecture Composant-connecteur
vue composant
21 / 56
Architecture composant-connecteur: Connecteur
Définition Connecteur de composant
Le connecteur modélise une interaction entre deux composants. C’est,
donc un composant spécialisé dans l’interaction, ne répondant pas
directement à un besoin fonctionnel / applicatif
Un connecteur peut modéliser une interaction simple (appel de
procédure) ou une interaction complexe (par exemple utilisation d’un
protocole comme http)
Un connecteur propose des rôles aux composants (ex : producteur,
consommateur, etc.)
C’est une entité de même rang que les composants applicatifs
22 / 56
Architecture composant-connecteur: Connecteur
Exemple de connecteur jsp
23 / 56
vue d’une architecture
Vue d’une architecture
La vue logique d’une architecture logicielle définit les principaux
composants d’une architecture sans se soucier des détails physiques
(équipements, machines, . . . etc.)
La vue physique s’intéresse au déploiement physique des différents
services
La vue physique est peu précise lors de la conception. Elle devient
concrète lors de la phase de déploiement.
La vue physique est peu précise lors de la conception. Elle devient
concrète lors de la phase de déploiement.
24 / 56
configuration de composant
Vue d’une architecture
Graphe de composants et de connecteurs spécifiant tout ou partie d’une
architecture selon un certain point de vue
⇒ Doit respecter des contraintes syntaxiques, sémantiques, spécifiques
⇒ Encapsulable dans un composant (non atomique) et réutilisable
⇒ La vue physique est peu précise lors de la conception. Elle devient
concrète lors de la phase de déploiement.
25 / 56
Principes fondamentaux de la bonne pratique fondamentaux
Principes SOLID
Single, Open, Liskov, Interface, Dependency
En programmation orientée objet, il existe cinq principes de conception
destinés (regroupés sous l’acronyme SOLID) qui visent à produire des
architectures logicielles plus compréhensibles, flexibles et maintenables.
Ces principes sont un sous-ensemble de nombreux principes promus par
l’ingénieur logiciel et instructeur américain Robert Cecil Martin
(familièrement connu sous le nom Uncle Bob).
Objectifs :
⇒de limiter les modules impactés ;
⇒de simplifier les tests ;
⇒de rester conforme aux spécifications qui n’ont pas changé.
26 / 56
Principes fondamentaux de la bonne pratique fondamentaux
Principes SOLID
Single, Open, Liskov, Interface, Dependency
Single Responsibility Principle (SRP) : Une classe ne doit avoir qu’une
seule responsabilité
Open/Closed Principle (OCP) : Programme ouvert pour l’extension,
fermé à la modification
Liskov Substitution Principle (LSP) : Les sous-types doivent être
substituables par leurs types de base
nterface Segregation Principle (ISP) : Éviter les interfaces qui
contiennent beaucoup de méthodes
Dependency Inversion Principle (DIP) :
Principaux composants en cours d’exécution et leurs interactions.
Les modules d’un programme doivent être indépendants
Les modules doivent dépendre d’abstractions
27 / 56
Principes fondamentaux de la bonne pratique fondamentaux
Appliquer des règles et des bonnes pratiques est crucial pour le succès
des projets de développement logiciel.
28 / 56
Cycle de vie d’un programme
Naissance :
Le code est beau, pur, et bien conçu.
Grande attention des développeurs lors de la création.
Enfance :
Apparition des premiers bugs.
Corrections rapides et ajout de fonctionnalités de manière
temporaire (rustines).
Le code devient moins pur et moins beau.
Adolescence :
Multiplication des bugs.
Augmentation des rustines.
Le code devient de moins en moins maintenable.
29 / 56
Cycle de vie d’un programme
Âge adulte :
Héritage de modifications passées rendant le code difficile à
améliorer.
Corrections de bugs complexes et susceptibles de créer de nouveaux
bugs.
Nécessité de continuer malgré les difficultés.
Vieillesse :
Fonctionnalités défaillantes, code non maintenable.
Impossibilité d’effectuer des modifications sans tout casser.
Attente de la fin du programme.
30 / 56
Conclusion
Bonnes pratiques :
Permettent au code de vieillir sereinement.
Maintiennent les fonctionnalités et la maintenabilité du code sur le
long terme.
Importance accrue en développement collaboratif pour éviter les
mauvaises répercussions sur les autres développeurs.
31 / 56
Comparaison
Comme pour un être humain, une bonne hygiène de vie (bonnes
pratiques de développement) est essentielle pour la longévité et la
performance du programme.
32 / 56
Définition du SRP
1. Principes SOLID
Single Responsibility Principle
Le “S” de SOLID signifie Single Responsibility Principle (SRP).
Définition : Une classe ne doit avoir qu’une seule raison de changer.
En français : Principe de responsabilité unique.
33 / 56
Exemple de Violation du SRP
Exemple : Implémentation d’un jeu comme le bowling.
Classe Game : Gestion des tours et calcul du score.
Problème : Deux responsabilités dans une seule classe.
Solution : Séparer en deux classes : Game pour les tours, Scorer pour le
score.
34 / 56
Pourquoi Séparer les Responsabilités ?
Chaque responsabilité est une direction de changement.
Couplage des responsabilités entraı̂ne :
Retests des autres responsabilités.
Modifications potentielles.
Redéploiement nécessaire.
Problèmes : Conceptions fragiles et bugs.
35 / 56
Avantages du SRP
Diminution de la complexité du code.
Amélioration de la lisibilité.
Meilleure organisation.
Modifications locales lors des évolutions.
Augmentation de la fiabilité.
Classes davantage réutilisables.
36 / 56
Illustration avec une Classe Rectangle
Classe Rectangle avec méthodes draw() et area().
Utilisée par GeometricApplication et GraphicalApplication.
Problème : Deux responsabilités (calcul et dessin).
37 / 56
Problèmes de la Conception Initiale
Inclusion de GraphicalInterface dans GeometricApplication.
Dépendance et couplage des responsabilités.
Risque de dysfonctionnement et nécessité de redéploiement.
38 / 56
Solution : Séparation des Responsabilités
Séparer les responsabilités en deux classes :
GeometricRectangle : Calcul géométrique.
GraphicalRectangle : Rendu graphique.
Avantages : Modifications indépendantes et meilleure fiabilité.
39 / 56
Définition
2. Open-Closed Principle (OCP)
Le ”O” de SOLID signifie Open-Closed Principle (OCP)
Définition par Robert Cecil Martin dans “Agile Software Development,
Principles, Patterns, and Practices” :
The Open/Closed Principle (OCP) : Software entities (classes, mod-
ules, functions, etc.) should be open for extension but closed for
modification.
Traduction :
Les entités logicielles (classes, modules, fonctions, etc.) doivent être
ouvertes à l’extension, mais fermées à la modification.
40 / 56
Application du Principe
Respecter l’OCP pour les classes implique :
Rajouter des fonctionnalités en ajoutant des classes (ouvert pour
l’extension)
Ne pas modifier le code existant d’une classe (fermé à la
modification)
41 / 56
Exemple d’Application
Pour une classe donnée :
On doit pouvoir l’étendre en créant une nouvelle classe
Ne pas la modifier pour y intégrer le comportement de la nouvelle
classe
42 / 56
Avantages de l’OCP
Le code existant n’est pas modifié, donc :
Pas besoin de le tester ou de le reconstruire, ce qui améliore la
fiabilité
Les classes sont plus réutilisables
Simplification de l’ajout de nouvelles fonctionnalités
43 / 56
Introduction au LSP
3. Liskov Substitution Principle (LSP)
Le ”L” de SOLID signifie Liskov Substitution Principle (LSP)
Un concept clé pour respecter OCP est l’héritage de code
L’héritage permet de créer des classes dérivées qui ajoutent de nouvelles
méthodes sans modifier la classe de base
44 / 56
Définition du LSP
3. Liskov Substitution Principle (LSP)
Définition par Robert Cecil Martin dans “Agile Software Development,
Principles, Patterns, and Practices” :
The Liskov Substitution Principle : Subtypes must be substitutable
for their base types.
Traduction :
Le principe de substitution de Liskov : les sous-types doivent être
substituables à leurs types de base.
45 / 56
Principe par Barbara Liskov
3. Liskov Substitution Principle (LSP)
Définition en 1988 :
S est un sous-type correct de T si pour chaque objet o1 de type S
il existe un objet o2 de type T tel que pour tous les programmes P
définis en termes de T, le comportement de P est inchangé lorsque
o1 est remplacé par o2.
46 / 56
Explication Simplifiée
Si une classe D étend une classe B (ou implémente une interface B) :
Un programme P écrit pour manipuler des instances de type B doit
avoir le même comportement avec des instances de type D
47 / 56
Importance du LSP
3. Liskov Substitution Principle (LSP)
Conséquences de la violation du LSP :
Supposons une fonction f prenant un objet de type B
Si un objet de type D donné à f provoque un comportement
incorrect, D viole LSP
Importance :
Éviter les comportements incorrects et garantir la substituabilité
48 / 56
Définition
4. Interface Segregation Principle (ISP)
Le ”I” de SOLID signifie Interface Segregation Principle (ISP)
Définition par Robert Cecil Martin dans “Agile Software Development,
Principles, Patterns, and Practices” :
The Interface Segregation Principle (ISP) : Clients should not be
forced to depend upon interfaces that they do not use.
Traduction :
Les clients ne doivent pas être obligés de dépendre d’interfaces
qu’ils n’utilisent pas.
49 / 56
Application du Principe
4. Interface Segregation Principle (ISP)
Éviter qu’un client ne voit une interface qu’il n’utilise pas
Appliquer ce principe revient souvent à éviter les interfaces avec
beaucoup de méthodes
50 / 56
Stratégies pour Appliquer l’ISP
4. Interface Segregation Principle (ISP)
Découper les interfaces en responsabilités distinctes (SRP)
Quand une interface grossit, questionner son rôle
Éviter d’implémenter des services non nécessaires dans les classes
Limiter les modifications lors de la modification de l’interface
51 / 56
Avantages de l’ISP
4. Interface Segregation Principle (ISP)
Moins de modifications du code existant, augmentant ainsi la fiabilité
Classes plus réutilisables
Simplification de l’ajout de nouvelles fonctionnalités
52 / 56
Définition
5. Dependency Inversion Principle (DIP)
Le ”D” de SOLID signifie Dependency Inversion Principle (DIP)
Définition par Robert Cecil Martin dans “Agile Software Development,
Principles, Patterns, and Practices” :
High-level modules should not depend on low-level modules. Both
should depend on abstractions (e.g. interfaces). Abstractions should
not depend on details. Details (concrete implementations) should
depend on abstractions.
Traduction :
Les modules de haut niveau ne doivent pas dépendre de ceux de bas
niveau. Les deux doivent dépendre d’abstractions (par exemple les
interfaces). Les abstractions, elles, ne doivent pas dépendre des
détails. Les détails (implémentations concrètes) doivent dépendre
des abstractions.
53 / 56
Application du DIP
Si une classe A utilise une classe B, il doit être possible de remplacer B
par une autre classe C
B et C sont des implémentations concrètes d’une classe abstraite (ou
d’une interface) utilisée par A
54 / 56
Stratégies pour Appliquer le DIP
Découpler le plus possible les différents modules du programme
Lier les modules quand nécessaire en utilisant des interfaces
Spécifier correctement le comportement de chaque module
55 / 56
Avantages du DIP
Permet de remplacer un module par un autre plus facilement
Modules plus facilement réutilisables
Simplification de l’ajout de nouvelles fonctionnalités
Facilitation de l’intégration
56 / 56