GUI GElement GElement ... GElement Wir kommen vermutlich gar nicht drumrum, jedes Diagrammelement einmal im GUI und einmal im Modell abzubilden: die GUI braucht Objekte die sich zeichnen und auf Events reagieren können; ein abgekoppeltes Modell ist aber sinvoll, damit ein entferner Client darauf genauso zugreifen kann wie die lokale GUI. observes observes observes observes Es gibt also zwei Objektarten, ich habe sie mal GElement und MElement genannt, wobei sämtliche Daten im MElement liegen, das GElement enthält nur GUI-Logik. Jedes GElement observiert sein MElement, um von Änderungen zu erfahren; das GUI observiert das Modell als ganzes, um über Ereignisse wie das Erzeugen neuer Elemente informiert zu werden. Es entstehen also zwei korrespondierende Objektgraphen. Fehlt also nur noch die Kopplung mit einem zweiten Prozess. Modell MElement MElement ... MElement Server Client GUI GUI GElement ... GElement GElement GElement GElement se rv es obs ... MElement observes ob observes ob se ob rv es se rve s MElement observes Modell ... ServerProxy s observes rve se ob s rve se ob ob es serv es obs erv observes observes observes observes ClientProxy GElement erv es Modell MElement ... MElement MElement MElement Das könnte dann so aussehen (ich benutze hier Proxy im Sinne von Stellvertreter – der ClientProxy vertritt den Client gegenüber dem Modell im Server). Anders als in meiner Tafelskizze braucht das Modell nicht zu wissen ob es im Client oder Server ist, da sich die Proxies als Observer anmelden, genau wie die GUI. Die MElemente verhalten sich auch in beiden Fällen gleich, bis auf einen Unterschied, das Locking – MElemente im Server machen das selbst, während MElemente des Clients dazu das entsprechende MElement im Server befragen müssen. Es wäre aber ungeschickt, jede MElement-Klasse in zwei Ausprägungen zu implementieren … Server Client GUI GUI GElement ... GElement GElement GElement GElement se rv es obs observes ob observes observes ob se ob rv es se rve s Modell ... ServerProxy s observes rve se ob s rve se ob ob es serv es obs erv observes observes observes observes ClientProxy GElement erv es Modell MElement MElement ... MElement MElement MElement ... MElement MasterLock MasterLock ... MasterLock SlaveLock SlaveLock ... SlaveLock … besser geht es per Strategy Pattern: MElemente machen das Locking gar nicht selbst, sondern bekommen ein Lock-Objekt, das es dann als MasterLock oder SlaveLock gibt. SlaveLocks fragen über den ServerProxy beim jeweiligen MasterLock an. Was im MasterLock drinsteckt weiß ich noch nicht, das könnte ein java.util.concurrent.locks.Lock sein oder vielleicht auch eine java.util.concurrent.Semaphore, je nachdem wie die Arbeitsteilung zwischen den Threads im Server aussieht. In jedem Fall ist es vermutlich gut, zusätzlich zu speichern wer das Lock hält, und diese Information (zusammen mit dem Lockstatus) den SlaveLocks mitzuteilen; dann kann man in der GUI kenntlich machen, welche Objekte gerade von wem bearbeitet werden, außerdem kann ein SlaveLock, das weiß dass das Lock vergeben ist, Locking-Anfragen sofort ablehnen ohne das MasterLock befragen zu müssen. Und nachdem ich die ganzen schönen Bildchen gemalt habe fällt mir auf, dass man die Trennung in GElement und MElement wahrscheinlich doch nicht braucht. Mist. Es gibt gute Argumente gegen die Trennung: Eine Trennung von Inhalt und Darstellung kann es bei dieser Anwendung eigentlich gar nicht geben, denn bei einem Diagramm ist die Darstellung der Inhalt; und es könnte Situationen geben, in denen das Modell das konkrete Aussehen eines Elements sehr genau kennen muss – z.B. wenn eine Kante wissen möchte, wo sie sich an einen Knoten anheften kann. Damit bleibt wohl als einziger Vorteil der Trennung die erhöhte Komplexität.
© Copyright 2025 ExpyDoc