Observer-Muster

DerMauri

Grünschnabel
Hi,

ich habe eine Frage bzgl. des Observer-Musters.

Ich möchte nicht ein Subjekt von mehreren Observern beobachten lassen, sondern mehrere Subjekte von genau einem Beobachter. Daher habe ich den Beobachter als Singleton modelltiert und ihn bei den Subjekten jeweils registriert. So weit, so gut.

Nun möchte ich aber den Observer aus obiger Beschreibung wiederum beobachten. Wie kann ich das in Java implementieren?

Also Subjekte A, B und C werden von Observer X beobachtet. Observer X ist wiederrum das zu beobachtende Subjekt für Observer Y:
Y beobachtet X beobachtet A, B, C

Ich habe jetzt schon einige Stunden mit der Foren und Googlesuche zugebracht, aber so langsam fürchte ich dass vor mir noch keiner das Problem hatte.

Gruß
Marco
 
Hallo,

hast du die Interfaces und Klassen von Java genutzt oder hast du was eigenes implementiert?

Grob gesagt machst du aus dem Beobachter auch ein Subject, dann kannst du das auch beobachten.

MFG

zEriX
 
Ich befinde mich noch in der Entwurfsphase und plane das ganze mit Interfaces von Java zu machen.
Leider bin ich noch nicht so ganz fit. Ich frage mich konket, ob ich ein Klasse so definieren kann:

Code:
public class foo extends Observable implements Observer
 
Danke!
Sobald ich mit dem Implementieren beginne, werde ich das so versuchen. Ich wollte mich bloß vergewissern, dass ich keinen groben Entwurfs-Fehler mache.

Eine weitere Frage habe ich aber noch: Kann ich auch Datenbanken beobachten, so dass diese ein notify() auslösen, sobald beispielsweise einen neune Datensatz einfüge?

Vielen Dank noch mal.

Gruß
Mauri
 
Zuletzt bearbeitet:
Also ich habe eine Datenquelle X, welche verschiedene Datenquellentypen A,B,C (Email, Diskette, Webservice...) beobachten soll. Sobald beispielsweise ein Datensatz via Email eintrifft, soll die Datenquelle X darüber informiert werden und die Daten in eine Warteschlange einreihen. Ferner soll die Datenquelle X eine andere Klasse Y (welche die Weiterverarbeitung der Daten übernimmt) über das Vorhandensein neuer Daten informieren.
 
Danke!
Sobald ich mit dem Implementieren beginne, werde ich das so versuchen. Ich wollte mich bloß vergewissern, dass ich keinen groben Entwurfs-Fehler mache.

Eine weitere Frage habe ich aber noch: Kann ich auch Datenbanken beobachten, so dass diese ein notify() auslösen, sobald beispielsweise einen neune Datensatz einfüge?

Vielen Dank noch mal.

Gruß
Mauri



Hi,

die Idee ist super, leider feuern Datenbanken nicht Ereignissen. Habe ich auch schon oft vermisst. Datensets unter Windows können sowas.

Im Prinzip kann man das lösen, wenn auch nur properitär. Viele Datenbanken haben Schnittstellen zu Programmiersprachen. Damit könnte man Trigger in der DB einbauen, die bei Änderungen via Messaging (Windows Message Queing, JMS) oder Named Pipes oder was auch immer eine Nachricht an eine Anwendung schicken. Im Prinzip ist das Observer über Anwendungsgrenzen und sogar über Rechnergrenzen hinweg.

Nachteile:
Windows hat den Nachteil Plattform abhänging zu sein ;-), JMS braucht einen Server.


Im Grunde geht das so:

Du richtest eine Message-Queue auf einem JMS-Server ein. Das ist wie ein Postfach beim E-Mail Verkehr. Alle mögliche Anwendungen, vor allem Deine DBs können Daten dorthin schicken. Wenn eine Datenbank, wie zum Beispiel Oracle ein Java-Schnittstelle hat, ist das Null Problem. Deine Anwendung wird asynchron benachrichtigt, wenn Daten anliegen. Ist Deine Anwendung gerade down, speichert der JMS die Nachricht so lange. Das Ganze läuft Transaktionorientiert, der Verlust von Nachrichten wird bemerkt.

Wenns Dich interessiert, bzw. Deine Datenbank Java unterstützt hätte ich ein paar Beispiele. Wenn die DB andere Sprachen unterstützt müsstest Du warscheinlich etwas länger googlen....

Gruß
 
Zuletzt bearbeitet:
Hallo,

also ich würde das viel allgemeiner Aufbauen...
Eine Datenquelle repräsentiert man über ein ISource<TData> Interface, wobei TData der Datentyp / Nachrichtentyp ist der von der Datenquelle kommt.

Java:
    static interface ISource<TData> {
        TData provide();
    }

Ein Verarbeitungsziel wird über ein ISink<TData> Interface definiert.
Java:
    static interface ISink<TData> {
        void receive(TData data);
        boolean canReceive(Class<?> dataType);
    }

Nun kann man sich folgendes asynchrone Szenario vorstellen:
Java:
        while (!stopProcessing) {
            for (final ISource<?> source : sources) {
                final Future<Object> sourceFuture = executorService
                        .submit(new Callable<Object>() {
                            public Object call() throws Exception {
                                return source.provide();
                            }
                        });

                executorService.execute(new Runnable() {
                    public void run() {
                        try {
                            final Object data = sourceFuture.get();

                            for (final ISink<? super Object> sink : sinks) {
                                if (sink.canReceive(data.getClass())) {
                                    executorService.execute(new Runnable() {
                                        public void run() {
                                            sink.receive(data);
                                        }
                                    });
                                }
                            }

                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        } catch (ExecutionException e) {
                            e.printStackTrace();
                        }

                    }
                });
            }

        }

So erhöht man die Geschwindigkeit durch Parallelisierung der Verarbeitung. Weiterhin kann man über die ISink / ISource Abstraktion ziemlich flexibel alles mit allem verknüpfen.

Gruß Tom
 
Zurück