Strategy Pattern - Listener
Le motif écouteur (listener pattern) est un motif basique utilisé par la plupart des langages. Dans les faits, tout langages de Programmation Orienté Objet (POO) peut utiliser ce motif. Il permet d'écouter les événements d'un objet aisément.
I - L'interface
Un écouteur est une simple interface qui définit les événements que l'écouteur doit écouter.
public interface ErrorListener
{
public void onError(Throwable t);
}
II – Comment implémenter l'objet à écouter
La façon la plus commune est d'ajouter l'écouteur à une liste contenue dans l'objet à écouter permettant des les ajouter à l’exécution (runtime).
Exemple : Vous pouvez ajouter un écouteur à l'instant A, en ajouter un autre à l'instant B et supprimer les deux à la fin de l’exécution de l'événement B.
public class ObjectToListen
{
private List<ErrorListener> listeners = new ArrayList<ErrorListener>();
Maintenant que la liste est présente vous remarquerez qu'elle n'est accessible qu'à l’intérieur de la classe. Il va donc falloir ajouter des méthodes d'encapsulations (wrappers) pour y avoir accès.
public void addErrorListener(ErrorListener listener)
{
listeners.add(listener);
}
public void removeErrorListener(ErrorListener listener)
{
listeners.remove(listener);
}
Optionnellement
public List<ErrorListener> getErrorListeners()
{
return listeners;
}
}
III – Comment déclencher les événements
Pour déclencher un événements un simple appel à la méthode d'événement que vous voulez déclencher sur les écouteurs enregistrés.
for(ErrorListener listener : listeners) {
listener.onError(new Throwable("Erreur à écouter"));
}
Mais pour le moment aucun écouteur n'est enregistré sur cet objet.
IV – Enregistrer un écouteur
Quand vous enregistrez un écouteur vous devez implémenter son comportement également.
Après avoir instancier l'objet à écouter vous devez appeler la méthode permettant d'ajouter l'écouteur à l'objet, ici addErrorListener(ErrorListener);
public class Main
{
public static void main(String[] args)
{
ObjectToListen _objToListen = new ObjectToListen();
_objToListen.addErrorListener(new ErrorListener() {
@Override
public void onError(Throwable t)
{
// Faites ici ce que vous souhaitez de l'exception levée.
}
}
}
}
Le comportement est implémenté dans la méthode événementielle de l'écouteur à l'enregistrement.
Astuces : La porté de l'écouteur est sa propre classe, ici ErrorListener.
Donc si vous souhaitez utiliser des attributs en dehors de cette porté, vous devrez let définir en temps que final (immuable) pour les attributs locaux à une méthode et LeNomDeVotreClasse.this.votreAttribut pour les attributs de la classe parente.
V – Cas de test
ErrorListener.java :
public interface ErrorListener
{
public void onError(Throwable t);
}
ObjectToListen.java :
public class ObjectToListen
{
private List<ErrorListener> listeners = new ArrayList<ErrorListener>();
public void execute()
{
try {
String _str = null;
_str.isEmpty();
} catch (NullPointerException e) {
for(ErrorListener listener : listeners)
listener.onError(e);
}
}
public void addErrorListener(ErrorListener listener)
{
listeners.add(listener);
}
public void removeErrorListener(ErrorListener listener)
{
listeners.remove(listener);
}
}
Main.java :
public class Main
{
public static void main(String[] args)
{
ObjectToListen _objToListen = new ObjectToListen();
_objToListen.addErrorListener(new ErrorListener() {
@Override
public void onError(Throwable t)
{
System.err.println(t.getClass());
}
}
_objToListen.execute();
}
}
La sortie :
class java.lang.NullPointerException