Hmja… Serialisieren war etwas, was mir auch kurz in den Sinn kam, aber … ich bin kein Fan von Serialisierung für Dinge, die nicht damit zu tun haben, ein POJO auf die Platte oder über’s Netz zu verschicken. Ich denke, dass man sich da viele Fragen stellen (und - und das ist das Problem - sie auch beantworten ) muss, die man sich auch bei einer programmatischen Kopie stellen muss. Allerdings hat man über Serialisierung ggf. weniger Kontrolle. Da muss man sich dann auch überlegen, welche Fields transient
sind, ob/wie man readObject
und writeObject
implementieren muss, und was man mit dieser lästigen List<ProjectListener>
- Liste macht, wo als einer der Listener ggf. irgendeine Instanz einer anonymen inneren Klasse liegt, die zum MainController
gehört…
Vielleicht wäre es - im spziellen, wenn z.B. Project
schon Serializable
ist - die mit Abstand einfachste Lösung. Die Kopie wäre dann ja mit einem newProject = readFromBuffer(writeToBuffer(oldProject));
erledigt. Aber im allgemeinen würde ich „Serialisierung als clone()-Ersatz“ recht skeptisch sehen.
(Auch wenn das nicht nicht als „Empfehlung“ oder ein „Abraten“ rüberkommen soll. Die Aussagen hier sind ja alle unter dem Vorbehalt, dass ich das Projekt nicht kenne…)
Wenn das TreeModel händisch implementiert ist, und praktisch eine "TreeModel
-View auf das echte Project
" ist, wirst du ja vermutlich auch mit einigen CellEditor
-Klassen deinen Spaß gehabt haben. Es ist bisher natürlich schwer, abzuschätzen, wie schwierig es ist, die echten Änderungen „mitzuschreiben“.
(Nebenbei: Da einen echten UndoManager
einzuspannen ist zwar cool, aber auch wieder ein bißchen aufwändig. Ich hatte das mal in einem Projekt gemacht, und wenn man erstmal ein bißchen vom Boilerplate-Code für die Verwaltung hat, geht es einigermaßen, aber in Kombination mit einem großen, hierarchischen Objekt und kleinen CellEditors
in einem Tree könnte das auch wieder kompliziert werden)
Aber ganz allgemein sehe ich eben diese beiden Alternativen: Entweder auf einer Kopie arbeiten, oder jede einzelne Änderung so mitprotokollieren, dass sie rückgängig gemacht wird.
Eine Kopie des Objektes zu erstellen dürfte in den meisten Fällen einfacher sein. Wieder subjektiv: Ich versuche aber, Dinge wie Cloneable
und clone()
zu vermeiden. Genaugenommen kann ich mich nicht erinnern, das jemals echt implementiert zu haben. Aber wenn schon Joshua Bloch in „Effective Java“ (Item 11) da zur Zurückhaltung rät, hat man immerhin etwas, worauf man sich berufen kann .
Die Frage, ob Unterobjekte mitkopiert werden (sollen) stellt sich dabei praktisch immer. Grundsätzlich finde ich, dass Methoden/Konstruktoren da mehr Möglichkeiten bieten:
public static Project deepCopy(Project other) { ... }
public static Project shallowCopy(Project other) { ... }
-
public static void transferAllListeners(Project source, Project target) { ... }
(letzteres würde schon ziemlich wehtun, aber wäre wenigstens „systematisch“ und klar…)
(Nochmal die Betonung: Alles unter Vorbehalt. Vielleicht ist ein clone()
oder Serializable
die bessere/einfachere Lösung…)