Design Pattern Observer / Observable
🎯 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