C#Observateur

Ceci est un exemple implémentant (de manière simpliste) le schéma de conception Observateur en C#. Vous pourrez comparer par vous-mêmes avec des programmes équivalents dans les langages que vous connaissez.

L'interface RéactionClavier expose un service TouchePressée(). Ce service sera invoqué lors du rappel des abonnés.

Une cas particulier de RéactionClavier est un AfficheurTouche, qui affichera les touches pressées.

Un Signaleur pourra signaler l'occurrence d'un « événement » (au sens large, pas dans une acception technique). Un cas particulier de Signaleur est FinDeProgramme, dont le nom décrit bien la tâcheé.

Un Surveillant surveille une touche en particulier et, si cette touche est pressée, signale un Signaleur.

Un GestionnaireClavier est un singleton implémentant le schéma de conception Observateur. Il est capable de lire une touche et d'informer tous ses abonnées de la touche qui fut lue. Remarquez le constructeur static, qui est un constructeur de classe. invoqué une seule fois par programme, avant que les autres membres de la classe ne puissent être utilisés.

Le programme principal montre comment il est possible d'abonner quelques observateurs au gestionnaire et de lire, puis d'afficher des touches, de manière cyclique, jusqu'à ce que le signal de fin de programme ait été produit.

using System;
using System.Collections.Generic;

namespace Exemple06Observateurs
{
   interface RéactionClavier
   {
      void TouchePressée(char c);
   }
   class AfficheurTouche
      : RéactionClavier
   {
      public void TouchePressée(char c)
      {
         Console.WriteLine("Touche pressée: {0}", c);
      }
   }
   interface Signaleur
   {
      void Signaler();
   }
   class Surveillant
      : RéactionClavier
   {
      private Signaleur signaleur;
      private char touche;
      public Surveillant(Signaleur sign, char c)
      {
         if (sign == null)
            throw new Exception("Signaleur manquant");
         signaleur = sign;
         touche = c;
      }
      public void TouchePressée(char c)
      {
         if (c.ToString().ToLower().Equals(touche.ToString().ToLower()))
            signaleur.Signaler();
      }
   }
   class FinDeProgramme
      : Signaleur
   {
      private bool mort;
      public FinDeProgramme()
      {
         mort = false;
      }
      public void Signaler()
      {
         mort = true;
      }
      public bool Complété()
      {
         return mort;
      }
   }
   class GestionnaireClavier
   {
      private List<RéactionClavier> elems;
      private static GestionnaireClavier singleton = null;
      static GestionnaireClavier()
      {
         singleton = new GestionnaireClavier();
      }
      private GestionnaireClavier()
      {
         elems = new List<RéactionClavier>();
      }
      public static GestionnaireClavier Instance()
      {
         return singleton;
      }
      public void Abonner(RéactionClavier réac)
      {
         elems.Add(réac);
      }
      public void Désabonner(RéactionClavier réac)
      {
         elems.Remove(réac);
      }
      public void Exécuter()
      {
         char c = (char) Console.Read();
         foreach (RéactionClavier réac in elems)
         {
            réac.TouchePressée(c);
         }
      }
   }
   class Program
   {
      static void Main(string[] args)
      {
         GestionnaireClavier ges = GestionnaireClavier.Instance();
         ges.Abonner(new AfficheurTouche());
         FinDeProgramme fdp = new FinDeProgramme();
         ges.abonner(new Surveillant(fdp, 'q'));
         while (!fdp.Complété())
         {
            ges.Exécuter();
         }
      }
   }
}

Valid XHTML 1.0 Transitional

CSS Valide !