Programmation événementielle en php ...

Contenu du snippet

Salut,
Bon bah voilà, je me demandais comment faire pour faire de la programmation événementielle en PHP, c'est-à-dire la possibilité de définir des actions à effectuer lors d'un changement interessant dans l'état d'un objet. L'exemple que j'ai choisi pour illustrer la méthode que j'ai mis en place est très simple (et aussi très nul, mais je regardais Les Experts sur la 1, et du coup, ça m'a donné l'idée ...) : on a 2 classes : une classe voiture dont les instances ont la possibilité d'être démarrées et arrêtées, et on peut également incrémenter leur vitesse ; une classe policier dont les instances peuvent verbaliser. Dans notre exemple, si la vitesse est superieure à 50, alors le policier est averti : il explique alors la raison du procés verbal et arrête la voiture.

Source / Exemple :


<?php
/* -------------------- */
   class Delegate
   {
      private $Owner = null;
      private $MethodName = null;
      
      function __construct($owner, $method_name)
      {
         $this -> Owner = $owner;
         $this -> MethodName = $method_name;
      }
      
      function invoke($sender, $event)
      {
         $owner = $this -> Owner;
         $method_name = $this -> MethodName;
         $owner -> $method_name($sender, $event);
      }
   }
/* -------------------- */
   class Event
   {
      public $Description;
      
      function __construct($description)
      {
         $this -> Description = $description;
      }  
   }
/* -------------------- */
   class Car
   {
      public $Name = '';
      private $Started = false;
      
      public  $OverSpeed = array();
      private $Speed = 0;
      
      public function __call($method_name, $arguments)
      {
         if(substr($method_name, 0, 2) == 'on')
         {
            $event_name = substr($method_name, 2, strlen($method_name) - 2);
            if(property_exists($this, $event_name))
            {
               $listeners = $this -> $event_name;
               foreach($listeners as $listener)
               {
                  $listener -> invoke($arguments[0], $arguments[1]);
               }
            }   
         }
      }
      
      public function __construct($name)
      {
         $this -> Name = $name;
      }
      
      public function accelerate()
      {
         if($this -> Started)
         {
            $speed = &$this -> Speed;
            $speed += 10;
            if($speed > 50) $this -> onOverSpeed($this, new Event("Excès de vitesse"));
         }
         else echo 'Démarre la voiture avant d\'accélerer ! <br />';
      }
      
      public function start()
      {
         $this -> Started = true;
      }
      
      public function stop()
      {
         $this -> Started = false;
      }
   }
/* -------------------- */
   class PoliceOfficier
   {
      private $Matricule = null;
      
      function __construct($matricule)
      {
         $this -> Matricule = $matricule;
      }
      
      public function charge($sender, $event)
      {
         echo 'Ici l\'agent '.($this -> Matricule).'. Je dresse un procés verbal contre le conducteur de la '.($sender -> Name).' pour cause de '.strtolower($event -> Description).'. <br />';
         $sender -> stop();
         echo 'J\'ai arrêté l\'automobiliste ! Il est aussi complêtement bourré ! <br />';
      }
   }
/* -------------------- */
   $john = new PoliceOfficier('3845-5214');
   $porche = new Car('Porche');
   $porche -> OverSpeed[] = new Delegate($john, 'charge');
   $porche -> start();
   $porche -> accelerate();
   $porche -> accelerate();
   $porche -> accelerate();
   $porche -> accelerate();
   $porche -> accelerate();
   $porche -> accelerate();
   $porche -> accelerate();
/* -------------------- */
?>

Conclusion :


On a 2 autres classes qui sont mises en place : la classe Delegate qui permet d'appeller une methode particulière d'un objet particulier (le tout étant passé en paramètre lors de la construction) ; la classe Event, qui contient seulement une description de l'évenement. Il faudrait modifier cette classe pour la rendre plus interessante (date et heure de l'évenement, j'en sais rien moi ! ...).
L'idée du code est donc de créer une propriété dans la classe observé qui contient la liste de tous les délégués vers la méthode voulu des observeurs (listeners). Lorsque l'on veut déclancher l'évenement, il suffit d'appeller la méthode onNomDeLEvenement (que l'on détecte via la méthode magique __call() ...).
Je sais pas si c'est la meilleure manière et j'attends beaucoup de réactions et de critiques (et de conseils) dans vos commentaires.
++ !
LocalStone

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.