Methoden Observer-Pattern mit Consumer und accept( )

JimmyKudo

Mitglied
// Hallo Leute, ich hab ein großes Problem ^^
// Wenn die getMethode aufgerufen wird, soll die Listener-Methode benachrichtigt werden.
// Das ist mein Ansatz:


List<Consumer<Collection<N>>> observers = new ArrayList<>();

public void registerObserver(Consumer<Collection<N>> listener) {
this.observers.add(listener);
}

public void notifiyObserver(Collection<N> c) {
for (Consumer<Collection<N>> observer : observers) {
observer.accept(c);
}
}



public Collection<N> getMethode() {
notifiyObserver(ig.getNodes());
}

public void Listener(Consumer<Collection<N>> listener) {
registerObserver(listener);
}



// Ich weiß aber nicht ob das korrekt ist und wie ein Test in der
// MAIN-Methode aussehen könnte. Wie soll ich die
// Consumer<Collection<N>> listener definieren .
// listener = x ->sysout(x); macht nicht wirklich sinn.
 
Wenn Du Probleme hast, ein Interface mit Lambda Expression zu implementieren, dann mache es doch einfach erst einmal auf die gute alte Art und Weise um erst einmal das generelle Verständnis zu bekommen.

Und da wäre der Ansatz z.B. ein einfaches:
Consumer<Collection<N>> listener = new Consumer<Collection<N>>() {};
Und dann einfach die IDE die Methode implementieren lassen. Dann hast Du vermutlich etwas wie:

Java:
        Consumer<Collection<N>> listener = new Consumer<Collection<N>>() {
            @Override
            public void accept(Collection<N> s) {

            }
        };

Und die Methode kannst Du dann so füllen wie Du möchtest. Und das kann ggf. auch einfach zu einem lambda Ausdruck umgewandelt werden. Oder du implementierst einfach eine Methode, die die Parameter/Rückgabe wie die accept Methode hat und nutzt die Methodenreferenz.

Und: Was ist hier das N? Wenn das ein Generic ist, dann wirst Du ja vermutlich eine konkrete Implementation ansprechen wollen ...

Ansonsten noch paar Hinweise:
- Bei Code immer Code-tags nutzen (Oberhalb der Eingabe der </> Knopf)
- Methoden immer mit Verb und klein starten (public void Listener(Consumer<Collection<N>> listener) {)
 
Ich versuche seit 2 Tagen das gleiche Problen zu lösen, aber klappt leider nicht. kann mir jemand erklären, wie das funktioniert. Ich verstehe da gar nix und verstehe nichts was mit listener gemeint ist. Danke im Voraus!
 
Was genau ist denn das Problem? Wenn man das etwas besser erläutern würde, dann könnte man auch helfen. Den TE hatte ich so verstanden, dass er lediglich Probleme hatte, einen Consumer zu implementieren.

ObserverPattern ist ansonsten auf vielen Seiten relativ gut erläutert. Unter dem Strrich ist es einfach nur eine Vereinfachung, damit eine Klasse unabhängig von anderen Implementationen funktioniert. Nimm einfach einen Button in einer Oberfläche. Der Button kennt die Klassen nicht, die ggf. an seinem Status interessiert sind. Daher abstrahiert er das einfach und bietet an, alle zu Informieren, die an einer internen Aktion interessiert sind.
Beim Button kann es also einfach eine Information sein, dass er gedrückt wurde.

Dazu verwende ich in der Regel ein eigenes Interface. Das könnte hier ein ButtonPressed Interface sein. Und das hat dann eine Methode buttonPressed() oder so. Wer nun daran interessiert ist, der kann sich also bei dem Button melden und sagen: Bitte Informiere mich, wenn Du gedrückt wurdest. Und ich stelle dafür eben genau diese Methode parat (Indem man selbst das Interface implementiert, eine eigene Implementation anbietet z.B über anonbyme Klasse oder - so wie es ab Java 8 üblich ist - per Lambda oder Methodenreferenz).

Das ist also wie bei der Bank: Die haben da dann ggf. eine Liste, wer alles zu informieren ist, wenn Geld eingeht. Was da alles auf die Liste kommt ist offen. Wichtig ist nur: Die müssen eine klar definierte Schnittstelle anbieten. Das kann also z.B. sein, dass Du eine SMS bekommst, wenn Geld eingegangen ist. Es kann aber auch ein Mechanismus sein, der Geld direkt pfändet oder so. oder egal was man sich da noch vorstellt: Die Implementation des Kontos ist final. Daran muss man nichts mehr ändern - egal was da noch auf die Liste kommen könnte.

Ist das etwas verständlich so? Etwas anders erläutert findet man es z.B. hier: https://de.wikipedia.org/wiki/Beobachter_(Entwurfsmuster)
Ausführlich behandelt wird es auch in dem Buch "Entwurfsmuster von Kopf bis Fuß".
 
Ich versuchs mal. Am einfachsten könnte man es sich wohl so vorstellen:

Java:
package obs;

public interface Observer {
    void notify(Class<?> invoking, Object msg);
}

Java:
package obs;

import java.util.ArrayList;
import java.util.List;

public class Observable {
    private final List<Observer> observerList = new ArrayList<>();

    public void registerObserver(Observer o) {
        observerList.add(o);
    }

    public void notifyObservers(Class<?> invoking, Object msg) {
        for (Observer o : observerList) {
            o.notify(invoking, msg);
        }
    }
}

Java:
package obs;

public class TestObj extends Observable {
    public void test() {
        this.notifyObservers(this.getClass(), " says hello!");
    }

    public static void main(String[] args) {
        TestObj to = new TestObj();
        to.registerObserver(new Observer() {
            @Override
            public void notify(Class<?> invoking, Object msg) {
                System.out.println(invoking.toString() + msg.toString());
            }
        });

        to.test();
    }
}

TestObj soll überwacht werden. TestObj benachrichtigt alle registrierten Observer. Vorher registriert sich ein Observer bei TestObj. Der benachrichtigte Observer tut etwas mit der Nachricht.

Das ist auch schon alles.
 
Java:
public interface Observer {
    void notify(Class<?> invoking, Object msg);
}
wäre wahrscheinlich besser dieses interface bzw klasse als Generic klasse zu implementieren anstatt Object zu verwenden

hierbei vllt den ObjectProperty<???> von javafx vllt anwenden
 

Zurück
Oben