Design Pattern Observer / Observable

code 22 juin 2025
🎯 Objectif : lancer une/actions quand un traitement se déclenche suivant un caractère événementiel

Anti-Pattern

 

class RecuperateurBoursier            
  
  def initialize(code, limite_bas:, limite_haut: )  
    @limite_bas = limite_bas  
    @limite_haut = limite_haut  
    @code = code  
  end  
  
  def lancer  
    dernierevaleur = nil  
    loop do  
      valeur = Valeur.recuperer(@code)  
      print "Valeur courrante: #{valeur}\n"  
      if valeur != dernierevaleur  
        changed                   
        dernierevaleur = valeur  
        controller(valeur)  
      end  
      sleep 1  
    end  
  end  
  
  def controller(valeur)  
    if valeur < @limite_bas  
        print "--- #{Time.now}: Valeur #{valeur} sous la limite : #@limite_bas \n"  
  
    elsif valeur > @limite_haut  
        print "+++ #{Time.now}: Valeur #{valeur} au dessus de la limite : #@limite\n"  
    end  
  end  
end  
  
class Valeur            
  def Valeur.recuperer(code)  
    60 + rand(80) #simulation  
  end  
end  
  
scanner = RecuperateurBoursier.new("EPA:ORA",limite_bas: 80 , limite_haut: 120)  
scanner.lancer  

Sortie :

Valeur courrante: 94  
Valeur courrante: 110  
Valeur courrante: 116  
Valeur courrante: 136  
+++ 2023-06-09 13:41:25 +0200: Valeur 136 au dessus de la limite :  
Valeur courrante: 132  
+++ 2023-06-09 13:41:26 +0200: Valeur 132 au dessus de la limite :  
Valeur courrante: 129  
+++ 2023-06-09 13:41:27 +0200: Valeur 129 au dessus de la limite :  
Valeur courrante: 132  
+++ 2023-06-09 13:41:28 +0200: Valeur 132 au dessus de la limite :  
Valeur courrante: 119  
Valeur courrante: 77  
--- 2023-06-09 13:41:30 +0200: Valeur 77 sous la limite : 80  
Valeur courrante: 94  
Valeur courrante: 134  
+++ 2023-06-09 13:41:32 +0200: Valeur 134 au dessus de la limite :  
Valeur courrante: 133  
+++ 2023-06-09 13:41:33 +0200: Valeur 133 au dessus de la limite :  
Valeur courrante: 113  
Valeur courrante: 89  
Valeur courrante: 75  
--- 2023-06-09 13:41:36 +0200: Valeur 75 sous la limite : 80  
Valeur courrante: 89  
^Ctest.rb:23:in `sleep': Interrupt  
        from test.rb:23:in `block in lancer'  
        from test.rb:15:in `loop'  
        from test.rb:15:in `lancer'  
        from test.rb:50:in `<main>'
🔍 Constat : La classe Récupérateur doit être modifiée chaque fois que l'ont veut enregistrer un nouvel évènement à détecter

Pattern

 

require "observer"  
  
class RecuperateurBoursier            
  include Observable  
  
  def initialize(code)  
    @code = code  
  end  
  
  def lancer  
    dernierevaleur = nil  
    loop do  
      valeur = Valeur.recuperer(@code)  
      print "Valeur courrante: #{valeur}\n"  
      if valeur != dernierevaleur  
        changed                   
        dernierevaleur = valeur  
        notify_observers(Time.now, valeur)  
      end  
      sleep 1  
    end  
  end  
end  
  
class Valeur            
  def Valeur.recuperer(code)  
    60 + rand(80) #simulation  
  end  
end  
  
class Avertisseur          ### Classe Abstraite  
  def initialize(scanner, limite)  
    @limite = limite  
    scanner.add_observer(self)  
  end  
end  
  
class AvertisseurBas < Avertisseur  
  def update(heure, valeur)     # surcharge  
    puts 'titi'  
    if valeur < @limite  
      print "--- #{heure.to_s}: Valeur #{valeur} sous la limite : #@limite \n"  
    end  
  end  
end  
  
class AvertisseurHaut < Avertisseur  
  def update(heure, valeur)       # surcharge  
    puts 'toto'  
    if valeur > @limite  
      print "+++ #{heure.to_s}: Valeur #{valeur} au dessus de la limite : #@limite\n"  
    end  
  end  
end  
  
  
scanner = RecuperateurBoursier.new("EPA:ORA")  
AvertisseurBas.new(scanner, 80)  
AvertisseurHaut.new(scanner, 120)  
scanner.lancer 

Mots clés

Romain GEORGES

Open Source evangelist & Ruby enthousiast