La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

GPA789 Analyse et conception orientées objet

Présentations similaires


Présentation au sujet: "GPA789 Analyse et conception orientées objet"— Transcription de la présentation:

1 GPA789 Analyse et conception orientées objet
Professeur: Tony Wong, Ph.D., ing. Chapitre 9 Conception orientée objet et implantation ÉTS - GPA, (C) Tony Wong, Ph.D., ing.

2 Conception orientée objet (1)
L’objectif principal de la conception orientée objet est de déterminer le « comment faire ». La conception orientée objet consiste à apporter une solution informatique aux questions et problèmes dégagés lors de l’analyse orientée objet. Il faut donc penser en termes de solutions informatiques et de leurs implantations.

3 Conception orientée objet (2)
La conception orientée objet, tout comme l’analyse orientée objet, n’est pas un travail algorithmique. Cependant, il existe un ensemble d’activités reliées à la conception qui peuvent nous guider dans le travail. Attention! La liste des activités présentées ici ne sont pas données en ordre. De plus, certaines activités peuvent être réalisées en parallèle.

4 Conception orientée objet (3)
Expliciter la séquence des événements dans les diagrammes d’interactions.

5 Conception orientée objet (4)
Ajouter les messages reliés à la création et à la destruction des objets dans les diagrammes d’interaction. Ajouter la direction de navigation aux relations entre les classes. Ajouter les relations de dépendance dans les diagrammes de classes

6 Conception orientée objet (5)
Identification des attributs et opérations manquantes. Ajouter les variables membres et les fonctions membres nécessaires aux algorithmes à implanter. Identification des classes collection. Ajouter des classes collection (liste, vecteur, etc.) pour tenir compte de la multiplicité des objets. Utiliser des classes paramétrisées pour entreposer des objets de type quelconque.

7 Conception orientée objet (6)
Spécification des types et visibilité. Spécifier les types concrets (selon le langage de programmation à utiliser). Déterminer le niveau d’accès des variables membres et des fonctions membres (public, protected, private). Spécification des contraintes. Indiquer les contraintes sur les valeurs des variables membres. Les valeurs limites, leur quantité, etc. Indiquer les contraintes sur les fonctions membres Leur pré-condition et leur post-condition.

8 Conception orientée objet (7)
Établir les algorithmes. Pour chacune des fonctions membres importantes: Écrire l’algorithme en pseudo-code en respectant sa pré- condition et sa post-condition. Assurer le respect des contraintes appliquées aux variables membres. Souvent les algorithmes à appliqués sont suggérer dans le contrat des opérations (créé lors de l’analyse orientée objet). Le pseudo-code est traduit en instructions de programmation lors de l’implantation du logiciel. L’objectif principal de cette activité est de rendre compréhensible l’algorithme à implanter aux programmeurs.

9 Conception orientée objet (8)
Spécification des exceptions Souvent les exceptions sont générées par la violation: Des pré-conditions de fonctions membres. Des valeurs limites ou quantité de variables membres. On indiquera la possibilité d’exception par une relation de dépendance

10 Conception orientée objet (9)
Spécifier les éléments de l’interface graphique Il faut établir un modèle d’utilisation du logiciel Comment présenter à l’utilisateur les actions disponibles ? Comment indiquer le chemin logique pour accomplir une tâche ? Comment l’utilisateur peut-il enclencher une action ? Comment indiquer la progression d’une action enclenchée ? Comment l’utilisateur peut-il arrêter prématurément l’action enclencher ? Comment signaler la fin d’une action à l’utilisateur ? Le modèle d’utilisation doit viser la simplicité.

11 Conception orientée objet (10)
Identification et ajustement des bibliothèques Choisir les bibliothèques nécessaires à l’implantation du logiciel (i.e. C++ standard Library, STL, Tools.h++, etc.). Décider s’il faut étendre les classes de ces bibliothèques. Exemple: Création d’une sous-classe spécialisée Matrice dérivée de vector pour faciliter le calcul matriciel. Identification et ajustement du cadre de travail Choisir le cadre de travail nécessaire à l’implantation du logiciel (i.e. MFC, Visual Component, Fox Toolkit, etc.). Décider s’il faut étendre les classes du cadre de travail. Exemple: Création d’une nouvelle sous-classes CGraphView dérivée de CView de MFC pour faciliter l’affichage des courbes.

12 Conception orientée objet (11)
Réalisation des associations Le concept d’association n’existe pas dans les langages de programmation orientée objet. En C++ on doit utiliser les variables membres pour réaliser une association. Cas unidirectionnel

13 Conception orientée objet (12)
Cas bidirectionnel Consulter le chapitre 6 pour connaître la réalisation des relations (association, agrégation, composition, etc.) en C++.

14 Implantation à l’aide de C++ (1)
Transformation de la conception en code: Écrire la définition des classes. Écrire la définition des méthodes (fonctions membres). Écriture de la définition des classes  diagrammes des classes dégagées de la conception. Écriture de la définition des méthodes (fonctions membres)  contrats d’opération, diagrammes de collaboration ou de séquence dégagées de la conception. Il faut ajouter les constructeurs et le destructeur aux classes !!

15 Implantation à l’aide de C++ (2)
Déterminer le nombre de constructeurs d’une classe selon les critères suivants: Énumérer les différentes façons un objet d’une classe peut être créé. Ex: La création d’un objet de type NombreComplexe peut être réalisée de trois manières différentes: 1. On spécifie la partie réelle et la partie imaginaire 2. On spécifie la partie réelle seulement 3. On spécifie la partie imaginaire seulement On peut donner deux constructeurs pour tenir compte de ces situations de création: NombreComplexe(float rel,float imag=0)  Cas 1, 2. NombreComplexe(float imag)  Cas 3.

16 Implantation à l’aide de C++ (3)
Ajouter explicitement un constructeur par défaut à chacune des classes Un constructeur par défaut est celui qui n’accepte pas de paramètre ou tous les paramètres possèdent une valeur par défaut. Ex: NombreCompexe(); ou NombreComplexe(float rel=0, float imag=0); Il est utilisé dans la situation suivante: NombreComplexe cmplx; Si ce constructeur n’est pas défini explicitement dans le code, le compilateur va en générer un pour nous. Mais le constructeur par défaut généré par le compilateur ne fait rien !!! Donc, soyez prudent.

17 Implantation à l’aide de C++ (4)
Constructeur par défaut (suite) Si on veut empêcher la création d’un objet par son constructeur par défaut  le définir dans la section privée de la déclaration. : : : private: NombreComplexe() { } }; De cette façon, l’utilisation accidentelle du constructeur par défaut produira une erreur de compilation.

18 Implantation à l’aide de C++ (5)
Ajouter explicitement un constructeur de copie à chacune des classes Un constructeur de copie est celui qui accepte une référence à la classe elle-même. Ex: NombreCompexe(const NombreComplexe& c); Il est utilisé dans les situations suivantes: NombreComplexe cmplx; // constructeur par défaut NombreComplexe cmplx2 = cmplx; // de copie NombreComplexe cmplx3(cmplx); // de copie Si ce constructeur n’est pas défini explicitement dans le code, le compilateur va en générer un pour nous.

19 Implantation à l’aide de C++ (6)
Constructeur de copie (suite) Mais la capacité du constructeur de copie généré par le compilateur est limitée. Il ne peut que copier les variables membres par leur valeur. L’espace réservé par l’allocation dynamique n’est pas copié  seulement le contenu du pointeur est copié pas le contenu de l’adresse pointée !! Donc, il est plus prudent de toujours déclarer le constructeur de copie explicitement.

20 Implantation à l’aide de C++ (7)
Ajouter explicitement la surcharge de l’opérateur == à chacune des classes La plupart des classes de collection au type paramétrisé (liste, vecteur, tableau, etc.) exigent des éléments possédant l’opérateur ==. Autrement dit, pour pouvoir placer un objet dans une liste, l’objet doit posséder l’opérateur ==. Cet opérateur est utilisé par les classes collection d’une manière interne. Puisque les types de base possède déjà cet opérateur (on peut comparer des int, des float, etc.), cette exigence n’est pas apparente.

21 Implantation à l’aide de C++ (8)
Surcharge de l’opérateur == (suite) Pour éviter les problèmes de compilation, on doit surcharger systématiquement les classes importantes de notre conception. class NombreComplexe { public: : : : bool operator ==(const NombreComplexe& c) const { // réaliser la compariason entre l’objet reçu // c et cet objet } };

22 Implantation à l’aide de C++ (9)
Implanter les fonctions membres d’une classe: 1. Les fonctions membres « get/set » La protection des données consiste à placer les variables membres dans la section protected et private. L’accès des variables protégées et privées par le monde extérieur (les autres objets du programme) s’effectuera à l’aide des fonctions membres set/get.

23 Implantation à l’aide de C++ (10)
2. Les fonctions membres « affaires » Les fonctions membres affaires réalisent le comportement explicite, les tâches à accomplir de l’objet. Elles sont normalement accessibles par d’autres objets. Donc, elles sont souvent déclarées dans la section publique de la classe. Les fonctions membres affaires sont celles indiquées dans les diagrammes de classes, les diagrammes de collaboration (de séquence).

24 Implantation à l’aide de C++ (11)
3. Les fonctions membres « internes » Les fonctions membres internes aident à la réalisation du comportement de l’objet. Souvent l’algorithme d’une fonction membre est trop complexe à réaliser directement. On distribue la tâche à plusieurs fonctions membres (diviser pour régner). Les fonctions membres internes ne sont pas accessibles à l’extérieur de l’objet. Elles sont donc déclarées dans la section protégée et/ou privée de la classe. Les fonctions membres internes ne sont pas destinées à être utilisées par le monde extérieur.

25 Implantation à l’aide de C++ (12)
N’oubliez pas d’inclure les classes collection dans l’implantation. N’oubliez pas d’inclure les signaux d’exception dans l’implantation. Il faut donc instaurer la gestion des exceptions par try - catch. Réaliser les messages envoyés entre les objets par des appels de fonctions membres de ces objets. Utiliser les diagrammes de collaboration et/ou de séquence pour vous guider dans cette tâche.

26 Implantation à l’aide de C++ (13)
Réaliser les messages envoyés (suite) Remplacer les événements générés par l’utilisateur par des messages de l’interface graphique. Autrement dit, l’utilisateur communique avec le logiciel via l’interface graphique. Donc, le logiciel n’adresse pas directement l’utilisateur mais bien son interface graphique. Si la portabilité du code est important, créer des agents intermédiaires pour isoler le logiciel de l’interface graphique.

27 Implantation à l’aide de C++ (14)
Utiliser les diagrammes d’états pour aider à la programmation et à la validation du logiciel. Les diagrammes d’états indiquent le déroulement logique du logiciel en fonction des événements générés (en provenance de l’interface graphique et des objets). Ces diagrammes donnent les grandes étapes du logiciel.

28 Modèles de conception (1)
Application des patrons de conception. Des éléments de conception préfabriqués. Applicable dans des situations générales. Ce concept existe dans toutes les disciplines de l’ingénierie: Circuit à deux vitesses Redresseur double alternance

29 Modèles de conception (2)
Patrons de conception facilitent la réutilisation. Ils rendent l’application plus robuste. Réduisent le temps de conception. L’identification des patrons de conception: Le nom du patron Le contexte d’application La solution apportée Le diagramme explicatif

30 Modèles de conception (3)
Patron « ÉTAT » Situation: Le comportement d’un objet est dépendant de son état. L ’application de la logique conditionnelle (les if - then - else) est trop complexe ou n’est pas désirable. Solution: Créer une classe (objet-état) pour chaque état qui influence le comportement de l’objet (objet-contexte).

31 Modèles de conception (4)
Patron « ÉTAT » Solution (suite): Utiliser le polymorphisme et assigner les méthodes à chacun des objets-états pour gérer le comportement de l ’objet-contexte. Lorsque l ’objet-contexte reçoit un message qui change son état, le transmettre aux objets-états.

32 Modèles de conception (5)
Patron « ÉTAT » Diagramme:

33 Modèles de conception (6)
Patron « ÉTAT » Exemple:

34 Modèles de conception (7)
Patron « FAÇADE » Situation: Un système existant possède une interface qui est complète et complexe. Nous désirons utiliser uniquement un sous-ensemble des capacités l’interface. Ou encore, nous désirons l’utiliser d’une façon particulière. Solution: Créer une classe qui possède l’interface requise. Fait en sorte que l ’interface de la classe utilise les fonctionnalités désirées du système existant.

35 Modèles de conception (8)
Patron « FAÇADE » Diagramme:

36 Modèles de conception (9)
Patron « ADAPTEUR » Situation: Une classe cible contient les bonnes données et le bon comportement. Cependant, elle dispose d’une interface incompatible ou inconvénient à utiliser. Solution: Créer une classe adapteur. Envelopper l’interface de la classe cible par celle de la classe adapteur.

37 Modèles de conception (10)
Patron « ADAPTEUR » Diagramme: Exemple:

38 Modèles de conception (11)
Patron « PONT » Situation: Il est nécessaire de séparer le model de son implantation. Permettre l’évolution indépendante de ces deux facettes. En d’autres mots, découpler l ’ensemble des objets d’implantation de l’ensemble des objets qui les utilisent. Solution: Créer deux hiérarchies de classes. Une hiérarchie représente le modèle et le raffinement du modèle.

39 Modèles de conception (12)
Patron « PONT » Solution (suite): L’autre hiérarchie représente l’implantation du modèle et de son raffinement. Joindre les deux hiérarchies par la composition ou l’agrégation.

40 Modèles de conception (13)
Patron « PONT » Diagramme:

41 Modèles de conception (14)
Patron « PONT » Exemple:

42 Modèles de conception (15)
Patron « MANUFACTURE ABSTRAITE » Situation: Un ensemble ou une famille d’objets sont à créer. On ne veut pas utiliser la construction switch - case pour réaliser cette tâche. Une longue liste de switch - case n’est pas très orientée objet et la logique de création des objets (paramètres initiaux, dépendance, etc.) est difficile à maintenir et à modifier.

43 Modèles de conception (16)
Patron « MANUFACTURE ABSTRAITE » Solution: Créer une classe manufacture par famille d’objets à créer. Donc, autant de manufactures que de familles d’objets. Doter la classe manufacture la logique et l’interface nécessaire pour créer les objets de la même famille. Le client crée les objets désirés par l’intermédiaire des classes manufactures. Le client ne doit créer les objets désirés directement.

44 Modèles de conception (17)
Patron « MANUFACTURE ABSTRAITE » Diagramme:

45 Modèles de conception (18)
Patron « SINGLETON » Situation: La classe ClasseA n’a qu’une seule instance. On ne permet pas l’instanciation de plus d’un objet de ClasseA. On veut un mécanisme automatique qui force les programmeurs à ne créer qu’une seule instance de ce type.

46 Modèles de conception (19)
Patron « SINGLETON » Solution: class Editeur { private: static Editeur *Instance; Editeur() { } public: static Editeur *getInstanceEditeur() { return (Instance==0)?new Editeur : Instance; } };

47 Modèles de conception (20)
Patron « SINGLETON » Solution: Pour utiliser la classe Editeur ainsi conçue: Régler la valeur initiale de Editeur::Instance à zéro au début du programme ou dans un fichier .h Editeur *Editeur::Instance = 0; Obtenir une instance de Editeur par Editeur *ed1 = Editeur::getInstanceEditeur(); Editeur *ed2 = Editeur::getInstanceEditeur(); À de la structure de la classe (singleton), ed1 est identique à ed2. On ne peut pas créer une instance de Editeur par Editeur *mauvais1 = new Editeur; Editeur mauvais2;

48 Modèles de conception (21)
Patron « OBSERVATEUR » Situation: Un événement survient et nous devons notifier un ensemble d’objets de l’arrivée de cet événement. Solution: Créer une classe Distributeur qui est au courant des événements dans le système. Chaque objet désireux de recevoir la notification des événements reçus doit s’enregistrer auprès de Distributeur. Les objets qui reçoivent la notification des événements sont des observateurs.

49 Modèles de conception (22)
Patron « OBSERVATEUR » Diagramme:

50 Modèles de conception (23)
Patron « OBSERVATEUR » Situation: Un événement survient et nous devons notifier un ensemble d’objets de l’arrivée de cet événement. Solution: Créer une classe Distributeur qui est au courant des événements dans le système. Chaque objet désireux de recevoir la notification des événements reçus doit s’enregistrer auprès de Distributeur. Les objets qui reçoivent la notification des événements sont des observateurs.

51 Modèles de conception (24)
Patron « DÉCORATEUR » Situation: Un objet dispose d’un nombre de fonctions. Il est souhaité de pouvoir ajouter de nouvelles fonctionnalités à l’objet et ce, dynamiquement pendant l’exécution du programme. Solution: Créer une classe abstraite qui représente à la fois la classe originale et les nouvelles fonctions à ajouter.

52 Modèles de conception (25)
Patron « DÉCORATEUR » Solution (suite): La classe originale (celle où l’on désire ajouter de nouvelles fonctionnalités) est appelée la composante abstraite. Les classes renfermant les nouvelles fonctions sont appelées les décorateurs. Instancier les objets appropriés à partir de la composante abstraite.

53 Modèles de conception (26)
Patron « DÉCORATEUR » Diagramme:

54 Modèles de conception (27)
Patron « DÉCORATEUR » Exemple:

55 Modèles de conception (28)
Patron « DÉCORATEUR » Ainsi, Entête::ImprimeBillet()  Imprime l’en-tête puis exécute Décorateur::ImprimeBillet(). PiedPage::ImprimeBillet()  Exécute Décorateur::ImprimeBillet() puis imprime le pied de page. Décorateur::ImprimeBillet()  exécute comp->ImprimeBillet() si comp existe.

56 Modèles de conception (29)
Patron « DÉCORATEUR » Exemple: Composante *c = new Entete(new PiedPage(new Billet()));

57 Modèles de conception (30)
Patron « DÉCORATEUR » En exécutant c->ImprimeBillet() :

58 Modèles de conception (31)
.// La classe Composante abstraite n’est pas montrée .// .// Classe Composante concrète .class Billet : public Composante { .public: . void ImprimeBillet() { // imprimer le billet } .}; . .// Classe Décorateur abstrait .class Decorateur : public Composante { .private: . Composante *comp; . Decorateur(Composante *c) { comp = c; } . virtual void ImprimeBillet() { . if (comp != 0) . comp->ImprimeBillet(); . }

59 Modèles de conception (32)
// Classe Entete est un décorateur concret .class Entete : public Decorateur { .private: . void ImprimeEntete() { // Imprime le texte de l’entête } .public: . void ImprimeBillet() { . // 1) Imprimer Entete . ImprimeEntete(); . // 2) Imprimer le billet . Decorateur::ImprimeBillet(); . } .}; .

60 Modèles de conception (33)
.// Classe PiedPage est un décorateur concret .class PiedPage : public Decorateur { .private: . void ImprimePiedPage() { // Imprime le texte pied de page } .public: . void ImprimeBillet() { . // 1) Imprimer le billet . Decorateur::ImprimeBillet(); . // 2) Imprimer le pied de page ici . ImprimePiedPage(); . . } .};

61 Modèles de conception (34)
.// Voici comment on peut utiliser la composante concrète .Composante *c; .c = new Entete( new PiedPage( new Billet())); // Wow !! .c->ImprimeBillet();

62 N’oubliez pas: C++ est bien plus que du C.
Fin du chapitre 9 Étudier les patrons de conception présentés. Relever les activités nécessaires à la création du modèle de conception. Appliquer les remarques concernant la phase d’implantation. N’oubliez pas: C++ est bien plus que du C.


Télécharger ppt "GPA789 Analyse et conception orientées objet"

Présentations similaires


Annonces Google