ich habe mehrere Klassen, zb AThing, BThing, CThing. ein Thing kann u.a. die Eigenschaften eines anderen Things (desselben Typs) übernehmen, wobei gemeldet wird, was geändert werden musste, um alle Eigenschaften zu übernehmen. der code in AThing könnte folgendermaßen aussehen:
und der in BThing so:
nun ist es so, dass die Things sehr viele Gemeinsamkeiten haben, auch die ChangeReports. Ich hab daher eine abstrakte Klasse Thing und eine weitere abstrakte Klasse ThingChangeReport. Nur die Dinge, die wirklich nur AThing betreffen, werden in AThing gecheckt und in den AThingChangeReport geschrieben. ich habe also eine abstrakte methode wie
in dieser methode muss ich dann natürlich typüberprüfungen machen und casten.
okay und nun siehts so aus, dass ich noch ein paar weitere solcher methoden haben, die zuerst in der abstrakten klasse Thing etwas machen und der spezielle code wird dann eben in den subklassen abgearbeitet. es gibt auch noch weitere klassen à la AThingChangeReport, also solche, die mit dem jeweiligen typ in verbinbung stehen
da der code aber (mit allgemeinen typen) in Thing steht, also:
... entsteht dann viel unnötiger code in den implementierenden klassen.:
sind jetzt nur blöde beispiele. ich komme öfters in solche oder ähnliche situationen (was ähnliches findet sich zb hier: http://www.java-forum.org/de/viewtopic.php?t=52162&highlight=). wenn es nur sehr wenige solcher methoden gibt bzw. nur wenige things, dann denke ich meist nicht drüber nach. aber wenn nun zb jedes Thing 10 solcher methoden und ich habe 10 verschiedene thing klassen, dann hab ich schon 100 (unnötige) methoden oder aber ich habe überall im code viele casts (und eventuell typüberprüfungen). beides gefällt mir nicht, weshalb ich es mit generics probiert habe. das ganze wird dann aber extrem kompliziert:
das ganze funktioniert eigentlich toll! die abstrakte Thing-Klasse kann so selbst die richtigen typen returnieren, weiters brauche ich in den subtypen keine typüberprüfungen, weil Thing bereits die richtigen typen an die abstrakte methode weitergeben kann, es gibt keine casts, etc.
ABER es sieht IMO eben extrem unschön aus. speziell das "T extends Thing" übergebe ich ja eigentlich nur, damit Thing seinen eigenen speziellen Typ kennt (ging das irgendwie anders??) und die anderen Parameter wie ThingBox näher spezifiziert sind (also denselben generischen Thing-Typen haben müssen).
naja, ich weiß jetzt nicht wirklich, was ich tun soll. ich traue mir nicht wirklich zu, zu beurteilen wie gut/schlecht die generische lösung ist, auch im hinblick auf verständlichkeit/wartbarkeit des codes. eventuell nehme ich die generizität wieder raus und caste/überschreibe eben mehr...
bin aber auf jeden fall für alle anregungen dankbar. wie gesagt stellt sich mir dieses problem schon in mehreren varianten und ich überlege jedes mal wieder, wie es am besten zu lösen ist, ohne wirklich eine gute lösung zu finden (eventuell kann man es auch ganz anders machen?...)
Code:
public AThingChangeReport copySettings(AThing otherThing) {...}
und der in BThing so:
Code:
public BThingChangeReport copySettings(BThing otherThing) {...}
nun ist es so, dass die Things sehr viele Gemeinsamkeiten haben, auch die ChangeReports. Ich hab daher eine abstrakte Klasse Thing und eine weitere abstrakte Klasse ThingChangeReport. Nur die Dinge, die wirklich nur AThing betreffen, werden in AThing gecheckt und in den AThingChangeReport geschrieben. ich habe also eine abstrakte methode wie
Code:
public abstract void copyMoreSpecificSettings(Thing otherThing, ThingChangeReport) {...}
in dieser methode muss ich dann natürlich typüberprüfungen machen und casten.
okay und nun siehts so aus, dass ich noch ein paar weitere solcher methoden haben, die zuerst in der abstrakten klasse Thing etwas machen und der spezielle code wird dann eben in den subklassen abgearbeitet. es gibt auch noch weitere klassen à la AThingChangeReport, also solche, die mit dem jeweiligen typ in verbinbung stehen
Code:
public void setBox(AThingBox box);
public AThingBox getBox();
da der code aber (mit allgemeinen typen) in Thing steht, also:
Code:
public void setBox(ThingBox box);
public ThingBox getBox();
... entsteht dann viel unnötiger code in den implementierenden klassen.:
Code:
public void setBox(ThingBox box) {
// check instance of AThingBox
..
super.setBox(box);
}
public AThingBox getBox(); {
return (AThingBox) super.getBox();
}
sind jetzt nur blöde beispiele. ich komme öfters in solche oder ähnliche situationen (was ähnliches findet sich zb hier: http://www.java-forum.org/de/viewtopic.php?t=52162&highlight=). wenn es nur sehr wenige solcher methoden gibt bzw. nur wenige things, dann denke ich meist nicht drüber nach. aber wenn nun zb jedes Thing 10 solcher methoden und ich habe 10 verschiedene thing klassen, dann hab ich schon 100 (unnötige) methoden oder aber ich habe überall im code viele casts (und eventuell typüberprüfungen). beides gefällt mir nicht, weshalb ich es mit generics probiert habe. das ganze wird dann aber extrem kompliziert:
Code:
public abstract class Thing<T extends Thing, U extends ThingBox<T>, V extends ThingChangeReport<T>, ... {..}
das ganze funktioniert eigentlich toll! die abstrakte Thing-Klasse kann so selbst die richtigen typen returnieren, weiters brauche ich in den subtypen keine typüberprüfungen, weil Thing bereits die richtigen typen an die abstrakte methode weitergeben kann, es gibt keine casts, etc.
ABER es sieht IMO eben extrem unschön aus. speziell das "T extends Thing" übergebe ich ja eigentlich nur, damit Thing seinen eigenen speziellen Typ kennt (ging das irgendwie anders??) und die anderen Parameter wie ThingBox näher spezifiziert sind (also denselben generischen Thing-Typen haben müssen).
naja, ich weiß jetzt nicht wirklich, was ich tun soll. ich traue mir nicht wirklich zu, zu beurteilen wie gut/schlecht die generische lösung ist, auch im hinblick auf verständlichkeit/wartbarkeit des codes. eventuell nehme ich die generizität wieder raus und caste/überschreibe eben mehr...
bin aber auf jeden fall für alle anregungen dankbar. wie gesagt stellt sich mir dieses problem schon in mehreren varianten und ich überlege jedes mal wieder, wie es am besten zu lösen ist, ohne wirklich eine gute lösung zu finden (eventuell kann man es auch ganz anders machen?...)