Observer Umsetzungsproblem

raffi

Mitglied
Hallo, ich hab da ein minderschweres Umsetzungsproblem beim Thema Observer. Zu Beginn erstmal die Ausgangslage: Ich habe derzeit 4 Klassen und ein Interface, eine Main- (Verwaltungsklasse), eine Professur-, Lehrveranstaltungs- und eine Loggerklasse. Das Interface habe ich AddDataListener genannt mit der Methode dataAdded. Nun will ich, sobald eine neue Professur oder eine neue Lehrveranstaltung angelegt wird in einer Datei diese Änderung speichern. Dabei soll das ganze über Listener erfolgen.
Allerdings verstehe ich die Umsetzung des ganzen noch nicht richtig. Ich habe jetzt in meiner Mainklasse eine ArrayList vom Typ AddDataListener angelegt. In dieser Main wird dann am Ende der Methode zum Anlegen der Professur eine Methode fireDataAdded aufgerufen in der der für jedes Element der ArrayList vom Typ AddDataListener die Methode dataAdded aufgerufen wird. In der Klasse Logger wird dann einfach die Methode überschrieben.
Nun der relevante Quelltext:
Java:
public class Main {

	
	TreeMap<String, Professur> prof;
	SimpleInput in;
	int auswahl; 	//Menü-Auswahl Variable
	ArrayList<AddDataListener> ad;
	
	public Main () {
		prof = new TreeMap<String, Professur>();
		in = new SimpleInput();
		auswahl = 0;
		ad = new ArrayList<AddDataListener>();
	}
	
	public void profAnlegen () {
		Professur anlProf = new Professur();
		boolean flag = false;
		
		String key = in.readString("Kuerzel der Professur: ");
		do {
			for (String search : prof.keySet()) {
				if (search.equals(key)) {
					flag = false;
					break;
				}
				else {
					flag = true;
				}
			}
			if (!flag) {
				System.out.println("Kuerzel ist bereits vergeben.");
				key = in.readString("Kuerzel der Professur: ");
			}
		} while (!flag);
		
		
		String pBez = in.readString("Name der Professur: ");
		String pMail = in.readString("E-Mail Adresse der Professur: ");
		int mAnz = in.readInt("Mitarbeiterzahl: ");
		anlProf.setKuerzel(key);
		anlProf.setName(pBez);
		anlProf.setMail(pMail);
		anlProf.setMitarbeiterzahl(mAnz);
		prof.put(key, anlProf);
		fireDataAdded(key);
	}
	
	public void addListener (AddDataListener adl) {        //gehört die Methode hier rein?
		ad.add(adl);
	}
	
	public void removeListener (AddDataListener adl) {    //gehört die Methode hier rein?
		ad.remove(adl);
	}
	
	private void fireDataAdded (String kuerzel) {
		for (AddDataListener a : ad) {
			a.dataAdded(kuerzel);
		}
	}
	
	public static void main (String[] args) {
		Main r = new Main();
		r.go();
	}
}

Java:
public interface AddDataListener {

	public void dataAdded (String kuerzel);
}

Java:
public class Logger implements AddDataListener {

	@Override
	public void dataAdded(String kuerzel) {
		FileWriter fw;
		PrintWriter pw;
		BufferedWriter bw;
		
		try {
			fw = new FileWriter("Aenderungen.txt");
			bw = new BufferedWriter(fw);
			pw = new PrintWriter(bw);
			
			pw.println("Daten für die Professur mit dem Kuerzel "+kuerzel+" hinzugefügt");
			
		} catch (Exception e) {
			e.getMessage();
		}

	}

}

Ist der Aufbau so ersteinmal richtig oder ist das schon etwas falsch?

MfG
 

Meru

Bekanntes Mitglied
Der Aufbau des Observer-Musters ist in meinen Augen richtig.

Natürlich muss das Observable-Objekt (deine Main) die Methode implementieren, der die Observer aufnimmt ( "addListener (AddDataListener adl){...}" ). Selbiges gilt auch für das Entfernen.
 

Michael...

Top Contributor
Kann man so machen.
Aber in dem Fall scheint mir das ganze etwas "overengineered".
Wie viele "Beobachter" gibt's denn?
Die Main-Klasse stellt ja das zu beobachtende Objekt, wo wird denn später das Logger Objekt erzeugt?
 

raffi

Mitglied
Hallo,
mir stellt sich eben auch die Frage, wo ich das Loggerobjekt erzeugen muss. Ich hatte es schonmal testweise in der Main-Klasse erzeugt bzw. die ganze Loggerklase in die Main implementiert, aber ich will/kann nicht so recht verstehen, wo genau in diesem Fall die addListener-Methode aufgerufen werden muss. Eigentlich doch in der Methode zum Erstellen einer Professur oder?
Also in etwa so:
Java:
public class Main {

	
	TreeMap<String, Professur> prof;
	SimpleInput in;
	int auswahl; 	//Menü-Auswahl Variable
	ArrayList<AddDataListener> ad;
	Logger logger;
	
	public Main () {
		prof = new TreeMap<String, Professur>();
		in = new SimpleInput();
		auswahl = 0;
		ad = new ArrayList<AddDataListener>();
		logger = new Logger();
	}

	public void profAnlegen () {
		Professur anlProf = new Professur();
		boolean flag = false;
		
		String key = in.readString("Kuerzel der Professur: ");
		do {
			for (String search : prof.keySet()) {
				if (search.equals(key)) {
					flag = false;
					break;
				}
				else {
					flag = true;
				}
			}
			if (!flag) {
				System.out.println("Kuerzel ist bereits vergeben.");
				key = in.readString("Kuerzel der Professur: ");
			}
		} while (!flag);
		
		
		String pBez = in.readString("Name der Professur: ");
		String pMail = in.readString("E-Mail Adresse der Professur: ");
		int mAnz = in.readInt("Mitarbeiterzahl: ");
		anlProf.setKuerzel(key);
		anlProf.setName(pBez);
		anlProf.setMail(pMail);
		anlProf.setMitarbeiterzahl(mAnz);
		prof.put(key, anlProf);
		logger.dataAdded(key);
		fireDataAdded(key);
	}
	
	public void addListener (AddDataListener adl) {
		ad.add(adl);
	}
	
	public void removeListener (AddDataListener adl) {
		ad.remove(adl);
	}
	
	private void fireDataAdded (String kuerzel) {
		for (AddDataListener a : ad) {
			a.dataAdded(kuerzel);
		}
	}
	
	public static void main (String[] args) {
		Main r = new Main();
		r.go();
	}
}
Aber so wäre die fireDataAdded Methode ja sinnlos...
Listener müsste es zwei geben, einmal falls eine Professur hinzukommt und der zweite beim Hinzufügen einer Veranstaltung. Wobei ich ersteinmal erstres hinbekommen möchte.

MfG
 

Michael...

Top Contributor
mir stellt sich eben auch die Frage, wo ich das Loggerobjekt erzeugen muss. Ich hatte es schonmal testweise in der Main-Klasse erzeugt bzw. die ganze Loggerklase in die Main implementiert
Daher meine Frage. Wenn Du das Loggerobjekt in der Main-Klasse erzeugst, kannst Du Dir ja das OberServer/Observable Gedöhns sparen, das ja das Main Objekt seinen "Beobachter" kennt, das es ihn selbst erstellt.
Listener müsste es zwei geben, einmal falls eine Professur hinzukommt und der zweite beim Hinzufügen einer Veranstaltung.
Nein, der Listener reagiert allgemein auf Änderungen seines Observables, ob da jetzt eine Professur oder eine Veranstaltung hinzukommt ist da egal. Falls notwendig, kann man im Interface zwei Methoden deklarieren, oder über eigenes "Event" dem Listener mitteilen, was genau passiert ist.
 

raffi

Mitglied
OK, genau das habe ich mir auch gedacht. Es scheint auch irgendetwas an dem Schreiben in die Datei nicht zu funktionieren, da er eine Ausgabe macht wenn ich das Loggerobjekt in der Main erstelle und in der Methode dataAdded eine Konsolenausgabe mache. Aber das ist erstmal zweitens.
Wie komme ich denn aber über die fireDataAdded-Methode an die Ausgaben ran und wo müsste ich denn in meinem Fall die addListener-Methode aufrufen?
Eigentlich benötige ich doch das Interface, habe ich. Dann benötige ich den Logger der irgendwas ausgibt oder macht in dem er das Interface implementiert und die Methode(n) überschreibt. Dann brauche ich das Modell (das wäre in meinem Fall die Main, weil Verwaltungklasse mit hinzufügen u. ä. Methoden). Am Ende soll das ganze ja mit Swing benutzt werden, aber ich will es erstmal so richtig umsetzen. Mit Swing hätte ich ja dann noch die Klasse mit dem Frame und den Widgets. Dort wären ja dann z. B. Klassen wie OpenAction implementiert und in dieser würde ich dann das Modell aufrufen (meine Main) und von dort aus die addListener ausführen oder nicht?

MfG
 

Michael...

Top Contributor
Wenn Du später eh eine GUI dazu machst, solltest Du Dir mal dasMVC anschauen.
In Deiner jetztigen Konstellation, könntest Du in der in der main-Methode folgendes Schreiben:
Java:
public static void main (String[] args) {
    Main r = new Main();
    r.addListener(new Logger());
    ...
}
Da die main() aber zur Main() gehört, ist hier das Observer Pattern eher überflüssig
 
J

JohannisderKaeufer

Gast
Ganz überflüssig würde ich mal nicht behaupten.

Wie schon geschrieben gehören

Zeile 8
Logger logger;
sowie Zeile 15
logger = new Logger();

weg und der logger mit addListener(new Logger) in der main Methode hinzugefügt.

Um dem ganzen jetzt ein wenig mehr Sinn zu geben, kannst du eine weitere Klasse erstellen, die Konsolenausgaben erstellt.

Java:
public class ConsolenLogger implements AddDataListener {
 
    @Override
    public void dataAdded(String kuerzel) {
            System.out.println.println("Daten für die Professur mit dem Kuerzel "+kuerzel+" hinzugefügt");
    }

und diese mit einem einfachen
r.addDataListener(new ConsolenLogger());
in der main-Methode hinzufügen.

Das Observer-Pattern lohnt sich sobald man mehrere Observer hat, oder mehrere Sachen observieren möchte.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
M OOP Design Pattern - "extends Observable implements Observer" Allgemeine Java-Themen 0
GreenTeaYT Verstehe nicht ganz das Observer Pattern in einer Arrayliste? Allgemeine Java-Themen 3
S OOP JFrame als Observer eines JPanel Allgemeine Java-Themen 3
A Observer und Initialisierung Allgemeine Java-Themen 7
L Registrierung von Observer Allgemeine Java-Themen 4
G 2 Observable und ein Observer... Allgemeine Java-Themen 4
M MVC: PropertyChangeListener vs Java Observer & Observable Allgemeine Java-Themen 11
S Wie kann ein Observer mehrere Observables beobachten? Allgemeine Java-Themen 9
Z Observer/Observable & Grundlagen Allgemeine Java-Themen 6
K Verständnisprobleme bei Observer-Pattern mit größerem Datenmodell Allgemeine Java-Themen 32
nrg Java Observer in SysTray laufen lassen / Console schließen Allgemeine Java-Themen 2
T Observer vs Listener Allgemeine Java-Themen 18
A Observer Pattern: feuern bei neuer Referenz-Zuweisung? Allgemeine Java-Themen 8
V Threads und Observer Allgemeine Java-Themen 18
H Observer und Observable Allgemeine Java-Themen 3
U Verständnisschwierigkeiten Observer Pattern Allgemeine Java-Themen 18
B Observer vs Listener (GUI-Programmierung) Allgemeine Java-Themen 5
M Observer serialisieren Allgemeine Java-Themen 7
G Observer / Observable oder doch lieber Message Broker? Allgemeine Java-Themen 2
D Observer/Observable Pattern vs. Listener-Konzept Allgemeine Java-Themen 4
P Observer/TimerTask Allgemeine Java-Themen 3
P Observer Allgemeine Java-Themen 4
N Observer/Observable der JAVA-API od. eigene Implementierung Allgemeine Java-Themen 2
B Observer reagieren beim 2ten mal nicht Allgemeine Java-Themen 23
P Observer, nicht alle updates bearbeiten Allgemeine Java-Themen 2
P Abmelden beim Observer Allgemeine Java-Themen 4
N Observer Pattern Allgemeine Java-Themen 2
M Frage zu update Methode von Observer! Allgemeine Java-Themen 40
lhein Tutorial zu Observer / Observable? Allgemeine Java-Themen 6
G problem mit dem observer pattern Allgemeine Java-Themen 3
S Observable und Observer Allgemeine Java-Themen 10
G Frage zu (mehrfachem) Observable/Observer Allgemeine Java-Themen 2
G Frage zum Observer Pattern Allgemeine Java-Themen 4

Ähnliche Java Themen

Neue Themen


Oben