Vous êtes sur la page 1sur 25

CAHIE

R
D’ETU
DE ET
Prosit Uml (dp)+ outils de
l’ingenieur

Créé par : Nwantou Tchouameni Joy Patricia


Pilote : Humphrey Mbeng Nkongho Ojong
Promotion : X2026
Table des matières

I. Analyse du contexte

II. Analyse des besoins

III. Définition de la problématique


IV. Définition des contraintes
V. Plan d’action

VI. Réalisation du plan d’action


VII. Validation des hypothèses

VIII. Conclusion

IX. Bilan critique du travail effectué


X. Références des méthodes et outils utilisés

I. Analyse du contexte

Lors d’un échange, un maitre tuteur se rend compte que son étudiant pense que le
développement se limite à coder et décide donc de lui apprendre les bases de la conception
1
II. Analyse des besoins
 Installation et utilisation des outils de développement
 Acquisition des compétences en conception logicielle
 Amélioration de l’efficacité du code

III. Définition de la problématique

Comment concevoir un programme qui respecte les principes de qualité logicielle sans toutefois
le lancer ?

IV. Définition des contraintes

 Coder de A à Z sans lancer une seule fois le programme


 Temps alloué pour l’acquisition des compétences en conception
 Utiliser méthode TDD
 Utiliser les outils de modélisation UML
 Respecter les principes SOLID de qualité logicielle

V. Plan d’action
 Définition des mots clés
 Etude de la modélisation UML
 Etude des principes SOLID de qualité logicielle
 Etude de la méthode TDD
 Etude des Design Patterns
 Prise en main des outils de développement et de modélisation
 Concevoir un programme en respectant les bonnes pratiques de conception logicielle

VI. Réalisation du plan d’action

1. Définition des mots clés

a. Modélisation UML : Le langage UML (Unified Modeling Language) est


constitué de diagrammes intégrés utilisés par les développeurs informatiques
pour la représentation visuelle des objets, des états et des processus dans un
logiciel ou un système.

b. Principe SOLID : ensemble de principes de conception logicielle qui visent


à améliorer la maintenabilité, la flexibilité et la compréhension du code source.

c. TDD : Test-Driven Development (TDD), ou développement piloté par les


tests en français, est une méthode de développement de logiciel qui consiste à
concevoir un logiciel par des itérations successives très courtes (ou petits pas),
telles que chaque itération est accomplie en formulant un sous-problème à

2
résoudre sous forme d'un test avant d'écrire le code source correspondant, et où
le code est continuellement remanié dans une volonté de simplification.

d. Design Pattern : Arrangement caractéristique de modules, reconnu comme


bonne pratique en réponse à un problème de conception d'un logiciel.

e. Concevoir : Fait de visualiser et de représenter les parties d’un système ou un


système entièrement et prédire son fonctionnement.

2. Etude de la modélisation UML

Unified Modeling Language (UML) est un langage de modélisation visuel utilisé pour
spécifier, visualiser, construire et documenter les composants d’un système logiciel. Il offre une
approche commune et compréhensible pour la conception et la modélisation de systèmes
logiciels complexes. Dans cet article, nous découvrirons ce qu’est le UML et comment il peut
être utilisé pour améliorer le processus de développement logiciel.

Description de la méthode UML


La méthode Unified Modeling Language (UML) est une méthode de conception graphique des
systèmes informatiques. Elle a été développée par Grady Booch, James Rumbaugh et Ivar
Jacobson et publiée par l’Object Management Group (OMG). La méthode UML a été conçue
pour être utilisée pour modéliser des systèmes informatiques complexes. Elle est orientée objet
et permet aux concepteurs de modéliser les systèmes informatiques et leurs composants à l’aide
d’un ensemble de symboles et de langages spécifiques.

Les principaux éléments d’un diagramme UML sont les classes, les associations, les objets, les
propriétés et les relations. Les diagrammes UML sont généralement organisés en quatre
sections principales : la structure, la dynamique, le comportement et l’environnement. Les
classes sont des types d’objets qui contiennent des données et des méthodes. Les associations
représentent la relation entre les classes et peuvent être définies comme « fortes » ou « faibles ».
Les objets sont des instances d’une classe qui peuvent interagir entre eux. Les propriétés sont
des attributs qui identifient un objet et ce qu’il peut faire. Les relations représentent la façon
dont les objets interagissent entre eux.

Les diagrammes UML peuvent également être utilisés pour créer des diagrammes de flux qui
montrent le flux des données à travers différents composants du système. Des diagrammes de
séquence peuvent également être utilisés pour montrer comment différents objets interagissent
entre eux à un moment donné. Ces diagrammes permettent aux concepteurs de voir clairement
le comportement du système à un moment donné et comment il va évoluer à l’avenir.

3
UML : Comment ça marche
UML fournit une syntaxe standardisée et un ensemble de règles qui permettent aux concepteurs
de capturer plus facilement leurs idées et de les communiquer efficacement entre collègues. La
capacité d’utiliser ce langage standard permet aux concepteurs de mieux comprendre leurs
propres conceptions, ainsi que celles des autres.

UML est composé de plusieurs diagrammes qui sont être utilisés pour représenter différents
aspects d’un système ou processus. Les principaux types de diagrammes UML sont :

 Le diagramme de cas d’utilisation


 Le diagramme de classes
 Le diagramme de séquence
 Le diagramme d’états
 Le diagramme d’activités
 Le diagramme déployer

Chacun d’eux fournit une vue différente du système et permet aux concepteurs et développeurs
d’avoir une meilleure compréhension de celui-ci.

Le diagramme de cas d’utilisation est un schéma qui montre comment un utilisateur interagit
avec un système. Il permet aux concepteurs de comprendre comment le système devrait réagir à
diverses actions externes telles que la saisie de données ou l’envoi d’instructions.

Le diagramme de classes sert à illustrer les relations entre les différents objets présents dans un
système. Il fournit une vue structurée des objets, des attributs et des méthodes associés à chaque
classe.

Le diagramme de séquence montre la chronologie des événements qui se produisent au cours


d’une interaction entre les objets du système, en indiquant quand et comment ils interagissent.

Le diagramme d’états montre comment l’état du système change au fur et à mesure que les
événements se déroulent. Il est particulièrement utile pour déterminer la façon dont un objet
réagira à certaines actions externes.

4
Le diagramme d’activité examine comment certaines activités sont effectuées par différents
objets du système afin que le processus soit exécutable.

Enfin, le diagramme déployer montre la structure physique du système, y compris


l’emplacement où chaque composant résidera lorsque le système sera mis en production.

UML fournit également des profils qui permettent aux concepteurs et développeurs d’affiner le
modèle en fonction des besoins spécifiques du projet. Les profils sont essentiellement des
extensions spécialisées qui peuvent être appliquées aux modèles UML pour ajouter plus de
précision et de complexité à l’existant. Ces profils peuvent être utilisés pour ajouter des
annotations supplémentaires aux modèles existants afin que ceux-ci reflètent exactement ce que
le client souhaite obtenir avec son projet.

UML : Avantages et inconvénients


Bien qu’il offre flexibilité et puissance, UML n’est pas sans limites. C’est un langage complexe
qui doit être interprété correctement par les concepteurs et les développeurs avant qu’il puisse
être mis en œuvre efficacement. Afin qu’ils puissent travailler ensemble efficacement vers la
conception du produit ou du service du projet, Il est essentiel que tous les membres de l’équipe
projet soit formés à la signification des schémas UML.

Autre limitation : lorsque vous concevez un système à l’aide d’UML, vous ne pouvez pas
prendre en compte certains aspects tels que le code source réel ou la structure physique du
système. Cela peut venir entraver l’implémentation concrète.

Étant donné qu’UML est un langage visuel complexe avec de nombreuses conventions
différentes, il peut être très facile de faire des erreurs ou d’oublier certaines étapes importantes
lors du processus de modélisation.

Malgré ses inconvénients potentiels, UML reste un outil puissant pour représenter des concepts
de flux métiers complexes et fournit une norme commune pour documenter et partager
l’information entre les membres d’une même équipe projet.

3. Etude des principes SOLID de qualité logicielle

SOLID est l'acronyme des cinq premiers principes de conception orientée objet (OOD) de
Robert C. Martin (également connu sous le nom d' Oncle Bob ).

Remarque : Bien que ces principes puissent s'appliquer à différents langages de


programmation, l'exemple de code contenu dans cet article utilisera PHP.

Ces principes établissent des pratiques qui se prêtent au développement de logiciels avec des
considérations de maintenance et d'extension à mesure que le projet se développe. L'adoption
de ces pratiques peut également contribuer à éviter les odeurs de code, la refactorisation du
code et le développement de logiciels Agile ou Adaptatif.
SOLIDE signifie :

 S - Principe de responsabilité unique


 O - Principe ouvert-fermé
 L - Principe de substitution de Liskov
 I - Principe de ségrégation des interfaces
 D - Principe d'inversion de dépendance

5
L’intention de ces principes est de rendre les conceptions de logiciels plus compréhensibles,
plus faciles à entretenir et à évoluer.

Des exemples seront donnés en PHP, mais s’appliquent à tout langage POO.Maintenant,
regardons chaque principe un par un :

Single-responsiblity principle

Une classe ne devrait avoir qu’une seule responsabilité.

Une classe ne devrait être responsable que d’une seule tâche. Si une classe a plus d’une
responsabilité, elle devient couplée. Le changement d’une responsabilité entraîne la
modification de l’autre responsabilité.

La classe Car viole le SRP.

Comment cela viole-t-il SRP ?

SRP déclare que les classes devraient avoir une responsabilité, ici, nous pouvons dégager deux
responsabilités : la gestion de la base de données et la gestion des propriétés. Le constructeur et
« getCarName » gèrent les propriétés tandis que « saveCar » gère le stockage des voitures sur
une base de données.
Comment cette conception causera-t-elle des problèmes à l’avenir ?
Si l’application change d’une manière qui affecte les fonctions de gestion de base de données.
Les classes qui utilisent les propriétés de la classe Car devront être recompilées pour compenser
les nouveaux changements.

Pour rendre cela conforme à SRP, nous créons une autre classe qui gérera la seule
responsabilité de stocker une voiture dans la base de données :

Open-closed principle

Les entités logicielles (classes, fonctions, etc) doivent être ouvertes pour l’extension et non pour
la modification.
Retournons à notre classe Car :

6
class Car {
public function __construct(String name){ }
public function getCarName() { }
}
Nous voulons parcourir la liste des voitures et ajoutons pour chaque voiture le modèle
approprié.

public function carModel(Array $cars) {


foreach($cars as $car) {
if($car->name == 'Bmw')
echo('X25');
if($car->name == 'Audi')
echo('A7');
}
}
Array $cars = new array(new Car('Bmw'), new Car('Audi'));
carModel($cars);
La fonction carModel n’est pas conforme au principe open-closed car elle ne peut pas être
fermée contre de nouveaux types de voiture.

Si nous ajoutons un nouvel type, Mercedes:

Array $cars = new array(


new Car('Bmw'),
new Car('Audi'),
new Car('Mercedes')
);

Nous devons modifier la fonction carModel:

public function carModel(Array $cars) {


foreach($cars as $car) {
if($car->name == 'Bmw')
echo('X25');
if($car->name == 'Audi')
echo('A7');
if($car->name == 'Mercedes')
echo('Classe C');
}
}

7
Vous constatez, pour chaque nouvelle voiture, une nouvelle logique est ajoutée à la fonction
carModel. Ceci est un exemple assez simple. Lorsque votre application grandit et devient
complexe, vous verrez que l’instruction if sera répétée encore et encore dans la fonction
carModel chaque fois qu’une nouvelle voiture est ajouté.

Maintenant, comment rendre la fonction carModel conforme au principe OCP ?

class Car {
getModel();
}
class Bmw extends Car {
getModel() {
return 'X25';
}
}
class Audi extends Car {
getModel() {
return 'A7';
}
}
class Mercedes extends Car {
getModel() {
return 'Classe C';
}
}
public function carModel(Array $cars) {
foreach($cars as $car) {
echo($car->getModel());
}
}
Array $cars = new array(
new Car('Bmw'),
new Car('Audi'),
new Car('Mercedes')
);
carModel($cars);

Maintenant, si nous ajoutons une nouvelle voiture, la fonction carModel n’a pas besoin de
changer. Tout ce que nous devons faire est d’ajouter une nouvelle classe étendant la classe Car.

8
La fonction carModel est désormais conforme au principe OCP.

Liskov substitution principle

Une classe fille doit être substituable à sa classe mère.

Le principe Liskov spécifie que si la classe A est un sous-type de classe B, alors nous devrions
pouvoir remplacer B par A sans perturber le comportement de notre programme.

public function carEngine(Array $cars) {

foreach($cars as $car) {

if($car->name == 'Bmw')

echo(bmwEngine($car));

if($car->name == 'Audi')

echo(audiEngine($car));

if($car->name == 'Mercedes')

echo(mercedesEngine($car));

Array $cars = new array(

new Car('Bmw'),

new Car('Audi'),

new Car('Mercedes')

);

carEngine($cars);
Cela viole le principe LSP et également le principe OCP. Il doit connaître tous les types de
voitures et appeler la fonction Engine associée.

Pour que cette fonction suive le principe LSP, nous suivrons les règles suivantes:

 Si la classe mère (Car) a une méthode qui accepte un paramètre de type classe mère (Car),

sa classe fille (Bmw) doit accepter comme argument un type de classe mère (type Car) ou

un type de classe fille (type Bmw).

 Si la classe mère renvoie un type de classe mère (Car) ,sa classe fille doit renvoyer un type

de classe mère (type Car) ou un type de classe fille (Bmw).

9
Maintenant, nous pouvons ré-implémenter la fonction carEngine:

public function carEngine(Array $cars) {

foreach($cars as $car) {

echo($car->getEngine());

Array $cars = new array(

new Car('Bmw'),

new Car('Audi'),

new Car('Mercedes')

);

carEngine($cars);
La fonction carEngine se soucie moins du type de voiture passé, elle appelle simplement la
méthode getEngine. Tout ce qu’il sait, c’est que le paramètre doit être de type Voiture, soit la
classe mère soit sa classe fille.

La classe Car et ses classes filles doivent maintenant définir la méthode getEngine :

class Car {

getEngine();

class Bmw extends Car {

getEngine() {

//..

}
Comme cous constatez, carEngine n’a pas besoin de connaître le type de voiture pour renvoyer
son Engine, il appelle simplement la méthode getEngine du type Car parce que la classe fille
doit implémenter la fonction getEngine.

Interface segregation principle

1
0
Un client ne devrait jamais être forcé d’implémenter une interface ou une méthode
qu’il n’utilise pas.
Ce principe traite les inconvénients de l’implémentation des grandes interfaces. Regardons
l’interface Animal ci-dessous :

interface Animal {

sayMoo();

sayMeow();

}
Cette interface spécifie le son émis par des animaux. La classe Cat, Cow, etc implémentant
l’interface Animal doit définir les méthodes sayMoo(), sayMeow(), etc.

interface Animal {

sayMoo();

sayMeow();

class Cat implements Animal {

sayMoo(){

echo 'Moo...';

sayMeow(){

echo 'Meow...';

class Cow implements Animal {

sayMoo(){

echo 'Moo...';

sayMeow(){

echo 'Meow...';

1
1
C’est assez drôle de regarder le code ci-dessus. La classe Cat implémente la méthode sayMoo
dont elle n’a pas besoin, pareil pour la classe Cow qui implémente la méthode sayMeow.

Pour rendre notre interface Animal conforme au principe ISP, nous séparons les actions sur
différentes interfaces :

interface ICat {

sayMeow();

interface ICow {

sayMoo();

class Cat implements ICat {

sayMeow(){

echo 'Meow...';

class Cow implements ICow {

sayMoo(){

echo 'Moo...';

}
Interface segregation principle

Le module de haut niveau ne doit pas dépendre du module de bas niveau, mais ils doivent
dépendre d’abstractions.

Il arrive un moment dans le développement de logiciels où notre application sera largement


composée de modules. Lorsque cela se produit, nous devons clarifier les choses en utilisant
l’injection de dépendance.

4. Etude de la méthode TDD

Qu’est-ce que le TDD ?


TDD est l’acronyme de Test-Driven Development, que l’on peut traduire par “développement
dirigé par les tests”. L’idée est simple : lorsque l'on souhaite développer une nouvelle

1
2
fonctionnalité, on commence par écrire le test qui vérifie son fonctionnement. Dans un
deuxième temps, la fonctionnalité est développée pour que le test soit validé. Et rien de plus !

Se concentrer sur la fonctionnalité évite d'écrire du code sans qu’il réponde à une exigence
satisfaite par un test validé.

Oui, cela arrive, et même souvent ! 😣

Le principe consiste ensuite à travailler en petits cycles itératifs où l’on va :

 Ecrire le minimum de code possible pour faire passer le test ;


 Enrichir la base de tests avec un nouveau test ;
 Écrire à nouveau le minimum de code pour faire passer le test ;
 Et ainsi de suite…
Cette pratique nous vient de Kent Beck, l’un des signataires du Manifeste Agile. Il encourage
une conception simple de nos applications et rend le développeur plus confiant dans la capacité
de son code à faire correctement ce qu'il souhaite, sans qu'il s'y cache quelques bugs.

On parle de "conception simple", car le code devient de facto simple à tester, alors qu’avec du
code legacy, il n’est pas toujours évident de pouvoir tester facilement.

On appelle code legacy un code qui est souvent mal écrit, dont personne n'a plus la maîtrise, et
qui n'est pas testé.
Les étapes du cycle du TDD
Regardons plus en détail les différentes étapes du cycle TDD.

1. Écrire un test
La première chose à faire, lorsque l’on a besoin d’une nouvelle fonctionnalité, est d’écrire un
test. Cela implique de comprendre la fonctionnalité que l’on doit développer, ce qui est une
très bonne chose.

Oui, il m'est déjà arrivé de commencer à développer sans forcément comprendre tout ce que je

devais faire... ça donne confiance, hein ? 😜

2. Exécuter le(s) test(s)


Il faut ensuite exécuter le test que l'on vient d'écrire.

Dans la pratique, on exécute le nouveau test, ainsi que ceux déjà existants. Cela implique qu'ils
doivent être très rapides à exécuter, sinon nous perdrons trop de temps à attendre un feedback.
Certains IDE poussent même le vice en exécutant les tests en continu, pendant que l'on est en
train de développer, afin d'avoir un retour encore plus rapide !
Le test doit échouer, vu qu’aucun code n’a été écrit pour le faire passer. En général, il ne
compile pas non plus, car la méthode/classe n’existe même pas.

3. Écrire le code
Ensuite, on écrit le minimum de code permettant de faire passer le test, et seulement le
minimum. Si le code écrit n’est pas beau, ou fait passer le test de manière inélégante, ce n’est
pas grave. On relance tous les tests pour s’assurer que tout fonctionne.

Note : écrire le minimum de code permet de respecter les bonnes pratiques KISS et YAGNI.

 KISS correspond à Keep It Simple Stupid (ou des variantes) et incite à garder le code
simple.

1
3
 YAGNI (you ain't gonna need it) peut être traduit par “tu n’en auras pas besoin”. Cela
indique qu’en général, un développeur va vouloir anticiper des besoins ou des
fonctionnalités alors qu’il n’en aura peut-être pas l'utilité (et d’ailleurs, c'est souvent le
cas !). Cette bonne pratique peut aussi s’appliquer à l’architecture des solutions : vouloir
utiliser un gros framework, plein de patrons de conception, de choses génériques, alors
que, finalement, on ne veut qu'afficher simplement du texte dans une page web.
4. Remaniement du code
Dans cette phase, nous avons l’opportunité d’améliorer le code que nous avons écrit. Cela
permet de voir s’il ne peut pas être simplifié, mieux écrit, rendu générique. On retire les
duplications, on renomme des variables, des méthodes, des classes, etc., afin que le code soit
bien propre et exprime clairement son intention. On peut séparer les responsabilités,
extraire potentiellement des patrons de conception, etc.

En bref : on améliore le code !

5. On recommence à l'étape 1 !
Le cycle recommence. Si la fonctionnalité que l’on a écrite peut être mieux couverte par
d'autres tests, si l’on doit introduire d'autres cas pour tester la fonctionnalité, alors on écrit un
nouveau test. Puis on écrit du code pour le faire passer, on améliore le code, on écrit un
nouveau test, etc.

Les bénéfices du TDD


Nous avons donc un cycle vertueux, qui améliore notre base de tests, nous rend plus confiants
dans notre code et le rend plus propre, plus robuste et plus facile à maintenir.

On appelle en général ce cycle red/green/refactor.

"Red" (rouge) correspond à la couleur du test lorsqu'il échoue.

"Green" (vert) quand le test passe, bien sûr.

"Refactor" indique la phase de remaniement de code. Nous en reparlerons lorsque nous


choisirons un framework de test.
Comme on l’a vu, le TDD rend de facto le code prêt à être testé. Cela améliore son design de
testabilité. Grâce au TDD, le design d’une classe ou d’un code émerge de lui-même. En effet,
en se concentrant sur le cas d’usage qui découle du test écrit, le travail se fait d’abord sur le
contrat et ensuite sur l’implémentation.

Beaucoup d’études ont été faites sur le TDD. Il en ressort que les développeurs qui suivent ces
pratiques ont un code de meilleure qualité et sont plus productifs.

L’approche est plus itérative et l'on avance petit à petit. Des résultats sont rapidement visibles et
cela évite de se perdre dans plusieurs jours de développement avant de pouvoir espérer
obtenir quelque chose qui fonctionne, voire qui compile.

Et bien sûr, vous aurez plein de tests pour votre filet de sécurité et la confiance en votre code.

Attention, cependant, avoir beaucoup de tests ne veut pas forcément dire que les tests sont
représentatifs ou utiles. Il faut également apprendre à faire des tests qui apportent de la valeur,
ce que nous verrons un peu plus loin dans le cours.

5. Etude des Design Patterns

En génie logiciel, un modèle de conception est une solution générale reproductible à un


problème courant dans la conception de logiciels. Un modèle de conception n’est pas une

1
4
conception finie qui peut être transformée directement en code. Il s'agit d'une description ou
d'un modèle expliquant comment résoudre un problème qui peut être utilisé dans de
nombreuses situations différentes.

Utilisations des modèles de conception

Les modèles de conception peuvent accélérer le processus de développement en fournissant des


paradigmes de développement testés et éprouvés. Une conception logicielle efficace nécessite
de prendre en compte des problèmes qui peuvent ne devenir visibles que plus tard au cours de
la mise en œuvre. La réutilisation des modèles de conception permet d'éviter les problèmes
subtils qui peuvent causer des problèmes majeurs et améliore la lisibilité du code pour les
codeurs et les architectes familiers avec les modèles.

Souvent, les gens ne comprennent que comment appliquer certaines techniques de conception
logicielle à certains problèmes. Ces techniques sont difficiles à appliquer à un éventail plus
large de problèmes. Les modèles de conception fournissent des solutions générales,
documentées dans un format qui ne nécessite pas de détails liés à un problème particulier.

De plus, les modèles permettent aux développeurs de communiquer en utilisant des noms bien
connus et bien compris pour les interactions logicielles. Les modèles de conception courants
peuvent être améliorés au fil du temps, ce qui les rend plus robustes que les conceptions ad hoc.

Modèles de conception créatifs


Ces modèles de conception concernent tous l’instanciation de classe. Ce modèle peut être divisé
en modèles de création de classe et en modèles de création d'objets. Alors que les modèles de
création de classes utilisent efficacement l'héritage dans le processus d'instanciation, les
modèles de création d'objets utilisent efficacement la délégation pour accomplir le travail.

 Abstract Factory
Crée une instance de plusieurs familles de classes
 Builder
Sépare la construction d'un objet de sa représentation
 Méthode Factory
Crée une instance de plusieurs classes dérivées
 Pool d'objets
Évitez l'acquisition coûteuse et la libération de ressources en recyclant les objets qui ne
sont plus utilisés.
 Prototype
Une instance entièrement initialisée à copier ou cloner
 Singleton
Une classe dont une seule instance peut exister

Modèles de conception structurelle


Ces modèles de conception concernent tous la composition des classes et des objets. Les
modèles structurels de création de classes utilisent l'héritage pour composer des interfaces. Les

1
5
modèles d'objets structurels définissent des manières de composer des objets pour obtenir de
nouvelles fonctionnalités.


Interfaces Adapter Match de différentes classes
 Bridge
Sépare l'interface d'un objet de son implémentation
 Composite
Une arborescence d'objets simples et composites
 Décorateur
Ajouter dynamiquement des responsabilités aux objets
 Façade
Une classe unique qui représente un sous-système entier
 Flyweight
Une instance à granularité fine utilisée pour un partage efficace

Les données de classe privée


limitent l'accès des accesseurs/mutateurs

 Proxy
Un objet représentant un autre objet

Modèles de conception comportementale


Ces modèles de conception concernent tous la communication des objets de Class. Les modèles
comportementaux sont les modèles qui concernent le plus spécifiquement la communication
entre les objets.

1
6
 Chaîne de responsabilité
Une manière de transmettre une requête entre une chaîne d'objets
 Commande
Encapsuler une demande de commande en tant qu'objet
 Interprète
Une manière d'inclure des éléments de langage dans un programme
 Itérateur
Accéder séquentiellement aux éléments d'une collection
 Médiateur
Définit une communication simplifiée entre les classes
 Memento
Capturer et restaurer l'état interne d'un objet
 Objet nul
Conçu pour agir comme valeur par défaut d'un objet
 Observateur
Un moyen de notifier un changement dans un certain nombre de classes

État
Modifier le comportement d'un objet lorsque son état change

 Stratégie
Encapsule un algorithme dans une classe
 Méthode modèle
Différer les étapes exactes d’un algorithme à une sous-classe
 Visiteur
Définit une nouvelle opération dans une classe sans changement

Critique

Le concept de modèles de conception a été critiqué par certains dans le domaine de


l'informatique.

Cible le mauvais problème


Le besoin de modèles résulte de l’utilisation de langages informatiques ou de techniques ayant
une capacité d’abstraction insuffisante. Dans le cadre d'une factorisation idéale, un concept ne
doit pas être copié, mais simplement référencé. Mais si quelque chose est référencé au lieu
d’être copié, alors il n’y a pas de « modèle » à étiqueter et à cataloguer. Paul Graham écrit dans
l'essai Revenge of the Nerds .

Peter Norvig avance un argument similaire. Il démontre que 16 des 23 modèles du livre Design
Patterns (qui est principalement axé sur le C++) sont simplifiés ou éliminés (via la prise en
charge directe du langage) en Lisp ou Dylan.

Manque de fondations formelles


L’étude des modèles de conception a été excessivement ponctuelle, et certains ont soutenu que
le concept avait absolument besoin d’être formalisé. Lors de l'OOPSLA 1999 , le Gang of Four
a été (avec leur entière coopération) soumis à un procès-spectacle, au cours duquel ils ont été «

1
7
accusés » de nombreux crimes contre l'informatique. Ils ont été « reconnus coupables » par les
⅔ des « jurés » présents au procès.

Conduit à des solutions inefficaces


L’idée d’un modèle de conception est une tentative de normaliser ce qui constitue les meilleures
pratiques déjà acceptées. En principe, cela peut sembler bénéfique, mais en pratique, cela
entraîne souvent une duplication inutile du code. Il est presque toujours plus efficace d'utiliser
une implémentation bien réfléchie plutôt qu'un modèle de conception « à peine assez bon ».

Ne diffère pas significativement des autres abstractions


Certains auteurs affirment que les modèles de conception ne diffèrent pas significativement des
autres formes d'abstraction et que l'utilisation d'une nouvelle terminologie (empruntée à la
communauté de l'architecture) pour décrire les phénomènes existants dans le domaine de la
programmation est inutile. Le paradigme Modèle-Vue-Contrôleur est présenté comme un
exemple de « modèle » antérieur de plusieurs années au concept de « modèles de conception
». Certains soutiennent en outre que la principale contribution de la communauté Design
Patterns (et du livre Gang of Four) a été l'utilisation du langage de modèles d'Alexander comme
forme de documentation ; une pratique souvent ignorée dans la littérature.

6. Prise en main des outils de développement et de modélisation

Quelques outils :
 Visual studio community
 Visual paradigm comme logiciel de modélisation

7. Concevoir un programme en respectant les bonnes pratiques de conception


logicielle

Voici le diagramme de classe de la solution fait avec Visual Paradigm

1
8
Voici l’execution de notre programme fait en C# sur Visual Studio 2012 où l’on voit bien le
déplacement des atomes à des instants différents :

1
9
Voici un aperçu du code de notre programme :

2
0
L’on peut visualiser toutes les diverses classes et interfaces sur l’explorateur de solutions :

2
1
Pour exécuter des tests unitaires à l’aide de l’Explorateur de tests

1. Créez des tests unitaires qui utilisent les frameworks de test de votre choix.

Par exemple, pour créer un test qui utilise le framework MSTest :

a. Créez un projet de test.

Dans la boîte de dialogue Nouveau projet, développez Visual Basic,


Visual C# ou Visual C++, puis choisissez Test.

Sélectionnez Projet de test unitaire.

b. Écrivez chaque test unitaire en tant que méthode. Préfixez chaque


méthode de test avec l’attribut. [TestMethod]

2. Si les tests individuels n’ont pas de dépendances qui les empêchent d’être
exécutés dans n’importe quel ordre, activez l’exécution des tests parallèles à l’aide
du bouton bascule de la barre d’outils. Cela peut réduire considérablement le

temps nécessaire à l’exécution de tous les tests.

3. Dans la barre de menus, choisissez Test, Exécuter des tests unitaires, Tous les
tests.

La solution se construit et les tests s’exécutent.

L’Explorateur de tests s’ouvre et affiche un résumé des résultats.

Pour afficher la liste complète des tests : Choisissez Afficher tout dans
n’importe quelle catégorie.

Pour afficher les détails d’un résultat de test : Sélectionnez le test dans
l’Explorateur de tests pour afficher des détails tels que les messages d’exception
dans le volet d’informations.

Pour accéder au code d’un test : Double-cliquez sur le test dans l’Explorateur de
tests ou choisissez Ouvrir le test dans le menu contextuel.

Pour déboguer un test : Ouvrez le menu contextuel d’un ou de plusieurs tests,


puis choisissez Déboguer les tests sélectionnés.

Important

Les résultats affichés correspondent à l’exécution la plus récente. La barre de résultats colorée
affiche uniquement les résultats des tests qui ont été exécutés. Par exemple, si vous exécutez
plusieurs tests et que certains d’entre eux échouent, puis que vous n’exécutez que les tests
réussis, la barre de résultats s’affichera en vert.

Notes

Si aucun test ne s’affiche, assurez-vous d’avoir installé un adaptateur pour connecter


l’Explorateur de tests à l’infrastructure de test que vous utilisez.

2
2
Voici le résultat obtenu de l’exécution de nos tests :

VII. Validation des hypothèses

Il était question de :
o Étudier la modélisation UML
o Étudier le principe SOLID
o Étudier les étapes de conception d’un logiciel
o Étudier les différents design patterns
o Étudier les outils de développement logiciel

VIII. Conclusion

Nos pistes de solutions ont toutes été validé car elles nous ont permis de résoudre notre
problématique.

2
3
IX. Bilan critique du travail effectué

 Individuel : Ce prosit nous a permis de comprendre la formalisation d’un projet, en


apprenant à fournir les éléments nécessaires à la mise en œuvre de ce projet.
 Collectif : Après avoir étudié la notion de design pattern, nous avons appris comment
rendre un code compréhensible, flexible, et maintenable avec la méthode SOLID. Il en
ressort qu’un programme bien modélisé est plus approprié qu’un programme ne
respectant des principes d’architecture logicielle.

X. Références des méthodes et outils utilisés

- Groupe X3(Membres du groupe)


- Les principes SOLID - WayToLearnX
- https://sourcemaking.com/design_patterns
- https://openclassrooms.com/fr/courses/5641591-testez-votre-application-c/
5656581-decouvrez-les-principes-du-test-driven-development-tdd

2
4

Vous aimerez peut-être aussi