Maison numérique

Introduction

Depuis les débuts de la programmation, tout un tas de développeurs ont rencontré différents problèmes de conception. La plupart de ces problèmes étaient récurrents. Pour éviter aux autres développeurs de buter sur le même souci, certains groupes de développeurs ont développé ce qu'on appelle des design patterns (ou masques de conceptions en français). Chaque design pattern répond à un problème précis. L'objectif du dernier TD de ce semestre fut d'appréhender une petite application dans sa totalité, en appliquant notamment plusieurs de ces Design Pattern.

Design Pattern

Le concept de Design Pattern est issu des travaux de 4 personnes (Erich Gamma, Richard Helm, Ralph Johnson, et John Vlissides connus sous le patronyme de « Gang of Four ») dans leur ouvrage « Design Patterns: Elements of Reusable Object-Oriented Software » édité en 1995 et proposant 23 motifs de conception.
Un patron ou motif de conception peut être vu comme un document formalisant la structure d'une classe permettant de répondre à une situation particulière. Les motifs de conception sont classifiés selon trois grandes familles :

  • Motifs de création : Motif Abstract Factory, Motif Builder, Motif Factory Method, Motif Prototype, Motif Singleton.

  • Motifs de structuration : Motif Adapter, Motif Bridge, Motif Composite, Motif Decorator, Motif Facade, Motif Flyweight, Motif Proxy.

  • Motifs de comportement : Motif Chain of Responsibility, Motif Command, Motif Interpreter, Motif Iterator, Motif Mediator, Motif Memento, Motif Observer, Motif State, Motif Strategy, Motif Template Method, Motif Visitor.

Christopher Alexander, 1977.
« Chaque patron décrit un problème qui se manifeste constamment dans notre environnement, et donc décrit le cœur de la solution à ce problème, d’une façon telle que l’on puisse réutiliser cette solution des millions de fois, sans jamais le faire deux fois de la même manière »

Étude de cas

Description initiale : La maison numérique

Nous sommes dans un contexte futuriste, un futur proche mais prometteur : nous avons affaire à une maison 100 % numérique, bourrée de dispositifs multifonctions dans chaque pièce : des capteurs, détecteurs, déclencheurs, outils automatisé, etc...
Bon, dans le cadre du TD nous nous sommes tenu aux capteurs.
Une maison numérique est donc équipée de capteurs qui sont des composants qui permettent de relever des mesures et actionneurs (composant permettant d'agir sur d'autres composants en vue de modifier leur comportement ou leur état). Les “dispositifs” sont soit associés à la maison (par exemple, un thermostat central), soit associés à une partie de la maison (par exemple, un capteur de consommation électrique à l'étage, un détecteur de fumée dans l'espace enfant), aux pièces (interrupteurs, thermomètre…).
Un tableau de contrôle permet de visualiser les valeurs relevées par tous les capteurs de la maison.
Notre objectif est de permettre de :

  1. créer des maisons numériques auxquelles on peut ajouter des dispositifs,
  2. visualiser les valeurs des différents dispositifs contenus dans la maison.

Modèle final


Lors de l’analyse du sujet, nous avons premièrement et rapidement établi les 4 classes prédominantes du système, à savoir : La MaisonNumerique, la Partie, la Pièce et le Capteur. La maison numérique contenant donc une liste de parties. Une partie est un ensemble de pièces mais peut également contenir une (sous) partie. D’où l’utilité une classe abstraite Lieu. Un lieu peut se traduire sous la forme d’une pièce ou d’une partie, grâce à l’héritage. Lieu s’occupe de l’identification de l’élément pièce ou partie (un String Nom) et des capteurs que contient celui-ci. Une pièce étant un élément final, elle n’a aucune fonction supplémentaire. Quant à la partie, celle-ci à la particularité de pouvoir contenir des lieux : une partie peut contenir des sous parties, ou des pièces.
Nous avons donc là une application du patron de conception Composite.

Le Lieu est le composant, il représente est l'abstraction pour tous les composites, y compris ceux qui sont composés et déclare comme prévu l’interface (qui ne veut pas obligatoirement dire une Interface, car nous avons dans notre cas une classe abstraite) pour le comportement par défaut.

La Pièce est un composite, elle représente un composant pouvant avoir des sous- éléments (des pièces ou parties), stocke des composants enfants et permet d'y accéder grâce aux méthodes implémentées.

La Pièce est une feuille, elle représente un composant n'ayant pas de sous-éléments et elle implémente le comportement par défaut du composant (car en effet elle n’a pas de fonctionnalités supplémentaires).


Venons-en au vif du sujet : les pièces (et les parties) peuvent contenir des Capteurs. Il sont répartis en plusieurs classes : Capteur est une interface, très légère, qui impose un nom et une valeur. À partir de là nous avons un CapteurPassif qui simule un CapteurPhysique. La différence est que les capteurs “passifs” sont des capteurs qu'il faut interroger pour obtenir la valeur correspondante par exemple à une température ou un éclairage. À un capteur passif nous associons un capteur physique. De plus, un capteur passif peut modifier la valeur lue dans le capteur physique pour lui associer une unité.
Enfin, le TableauDeBord permet de visualiser les capteurs associés aux lieux qu'il surveille. Pour cela, à chaque fois que l'on ajoute un capteur aux lieux surveillés, il ré- affiche la valeur de tous les capteurs. Attention : si on surveille une partie de la maison, on surveille tous les capteurs de la partie, c’est à dire ceux dans toutes les pièces de la partie et pas seulement ceux qui sont en dehors des pièces. Pour cela, le tableau de bord et le Lieu auquel il est associé respectent le patron de conception Observer / Observable, la classe TableauDeBord est Observer et le Lieu est Observable : le tableau observe le lieu auquel il est confié et le lieu notifie le tableau de bord lorsqu’un capteur est ajouté.
Nous avons codé un scénario de création d’une maison en plus des tests unitaires de chaque classe, en vue de représenter la corrélation de chacune d’entre elle, car le respect de des patrons de conception en font qu’elles sont étroitement liées.

Nous avons donc une MaisonNumérique, appelé Palais Royal.
Il contient une partie Rez de Chaussée, une partie Extérieur et autre : 1er étage.
Dans le RDC se trouve deux pièces : le Salon et la Cuisine. Le RDC contient un thermostat (capteur).
Au 1er étage se situe deux chambres et un bureau. Chaque pièce continent un capteur. À l’Extérieur il y a un détecteur de présence.
Grâce au patron Composite nous pouvons facilement concevoir des parties contenant naturellement des pièces ou des sous parties, et ce un nombre théorique infini de fois.
Le Tableau de Bord est donc au courant de l’ajout de chaque nouveau capteur.


À propos

Ce TD permet de mettre en pratique tout ce que l’on a vu au cours des TD précédents. En effet nous avons dû réutiliser du code déjà produit via la classe CapteurPhysique et les codes ont été réalisé au mieux possible afin de respecter les principes SOLID, par exemple nous ne dépendons d’aucune classe concrète mais seulement de classe abstraite ou d’interface et les classes ont des responsabilités limitées.