OOP Architektur Problem

andreT

Aktives Mitglied
Hallo,

ich habe aktuell ein kleines Problem bei dem ich einen Tipp/Rat benötige.
Es geht um eine kleine API für Desktopanwendungen die aktuell immer nur eine Anwendung "verarbeiten" kann. D.h. es ist immer nur eine Anwendung gestartet und alle geöffneten Fenster gehören dieser einen Anwendung.
Damit sich die Fenster untereinander nicht kennen müssen, sich aber relativ zueinander positionieren können, wurde einst folgender Code/Mechanismus gebaut :
Der aktuelle Code sieht (stark vereinfacht!) so aus :

KLASSE MyJFrame
Code:
import javax.swing.JFrame;
public class MyJFrame extends JFrame {

	/*
	 * Konstruktor 01
	 * Konstruktor 02
	 * Konstruktor 03
	 * ...
	 */
	
	/**
	 * Überschrieben damit Fenster immer (zueinander) zentriert werden! 
	 */
	public void setVisible(boolean visible) {
		if(visible) {
			MyWindowManager.setActiveWindow(this);
		}
		
		super.setVisible(visible);
	}
}

KLASSE MyJDialog
Code:
import javax.swing.JDialog;
public class MyJDialog extends JDialog {

	/*
	 * Konstruktor 01
	 * Konstruktor 02
	 * Konstruktor 03
	 * ...
	 */
	
	/**
	 * Überschrieben damit Fenster immer (zueinander) zentriert werden! 
	 */
	public void setVisible(boolean visible) {
		if(visible) {
			MyWindowManager.setActiveWindow(this);
		}
		
		super.setVisible(visible);
	}
}

KLASSE MyWindowManager
Code:
import java.awt.Window;
public class MyWindowManager {
	private static Window activeWindow = null;
	
	/**
	 * Liefert das aktive Fenster! 
	 */
	public static Window getActiveWindow() {
		return activeWindow;
	}

	/**
	 * Kann Fenster (zueinander) zentrieren! 
	 */
	public static void setActiveWindow(Window window) {
		// Fenster (zueinander) zentrieren!
		window.setLocationRelativeTo(getActiveWindow());
		// Fenster aktiv setzen!
		activeWindow = window;
	}
}

Nun soll die API weiterentwickelt werden damit mehrere Anwendungen bzw. Plugins parallel gestartet werden können. Diese Plugins haben natürlich jeweils eigene Dialoge!
Das Problem : Der statische Zugriff auf MyWindowManager ist so ja nun nicht mehr möglich weil dort ja nicht zwischen den Anwendungen getrennt wird. Es kann dann also passieren das ein Fenster von Plugin2 plötzlich über/relativ zu einem Fenster von Plugin1 positioniert wird o.ä..
Was nun also tun?

Mein erster Ansatz war daß ich nun sowas wie einen PluginKontext halte der das Plugin ja eindeutig identifizieren kann. Problem hierbei ist nur das dieser Kontext ja dann überall hin durchgereicht werden muss, damit auch noch in der "hintersten anonymen Klasse" auch ein Fenster gestartet werden kann!.

Ich suche nun nach einer eleganten/cleveren/gängigen Möglichkeit dieses "Problem" möglichst komfortabel zu beheben. Gibt es für sowas nicht vllt. auch ein "Pattern" o.ä.. Eigentlich müsste sowas ja ein "gängiges" Problem sein, oder?

Hat jemand einen Tipp/Rat und/oder Erfahrung mit solch einem Problem?

Gruß
andre


--------------------

edit : Nur kleinere Compile-Fehler behoben 😉
 
Zuletzt bearbeitet:
> nur das dieser Kontext ja dann überall hin durchgereicht werden muss
das ist in der Tat ein allgemeines Problem, führt z.B. zu
Dependency Injection ? Wikipedia

mein Zusatz ist aber auch immer, dass man das gar nicht so an die große Glocke hängen muss,
ja, jede Klasse muss was an andere weiterreichen, aber so ist das Leben,
verwende für alles, z.B. Listener, möglichst Basisklassen, verstecke Initialisierungen in allgemeinen Methoden,
dann fällt das letzlich gar nicht mehr richtig auf

> damit auch noch in der "hintersten anonymen Klasse" auch ein Fenster gestartet werden kann!.

schreibe z.B.
Java:
addListener(button, new MyAction() {
   public void action() {
      getContext().xy();
   }
});
mit einer Methode addListener(), die das add() ausführt und gleichzeitig noch den übergebenen Listener initalisiert,
so fällt es im Code kaum weiter auf, das init kann aber nicht vergessen werden, falls man nicht zum normalen add() übergeht,

nebenbei kann man noch das nervige actionPerformed(ActionEven) von ActionListener in eine einfachere Methode ummodeln,
kann ein try/catch Exception mit Logging drumherum setzen, vielleicht mit MyRunAction automatisch einen Thread starten usw.,
Basisklassen sind mächtige Sache
 
In Android ist jede Komponente, die mit der App oder Android an sich interagieren möchte (außer reine Modell-Klassen) von einem
Code:
Context
abgeleitet, bzw. einem
Code:
ContextWrapper
, der eine
Code:
getApplicationContext()
vorschreibt. Man muss auch bei jeder zweiten Methode einen Kontext übergeben, wenn man bestimmte Komponenten benutzen will. Dieser
Code:
getApplicationContext()
ist in einer ABC implementiert und wird wie schon gesagt von jedem "Plugin" abgleitet.
 
Schon merkwürdig daß man sich schon erleichtert fühlt wenn man liest das etablierte Systeme solche "Probleme" ähnlich "trivial" lösen mussten 😀

Der Hinweis mit dem getContext().yx() setzt dem ganzen letztlich Krone auf!
Die Tatsache das JEDES Plugin eine abstrakte Klaase zum Starten überschreiben muss und diese dann garantiert auch nur einmal gestartet werden kann, bietet natürlich die komfortable Möglichkeit einer statischen getContext()-Methode an dieser. Und schon brauch man auch nichts mehr durchreichen. Der Kontext kann dann ja auch noch xy() usw. :toll:
So werd ich es bauen.

Danke für die Antworten!
Gruß
andre
 

Neue Themen


Zurück
Oben