Zitat von
alzaimar:
Meiner Meinung nach sollte man keine Konsistenzprüfung in einem Konstruktor vornehmen. Das ist zwar Geschmackssache, aber in meinen Augen durchaus sinnvoll: Beim Erstellen einer Instanz weiss ich noch gar nicht, ob sie später mal konsistenz ist oder nicht (gemäß der Theorie).
Jain.
Für stinknormale Klassen, die transiente oder persistente Daten deines Applikationsmodelles halten mag das zutreffen.
Aber es wird immer wieder Klassen geben, die sich
immer in einem konsistenten Zustand befinden
müssen.
Ein FileStream wäre so ein Fall.
Zitat:
Entweder implementiere ich das in einer Class Function und rufe die VOR der Instantiierung auf (praktisch, aber uncool)...
Klassische Factory,
IMHO sogar sehr cool, da de Prüfung
vor dem Allozieren von Speicher passieren kann.
Zitat:
, oder ich prüfe die Konsiszenz über eine stinknormale Methode, die die Eigenschaften, die ich ja (reine Lehre) erst zuweisen muss, naturgemäß bei der Instantiierung noch nicht bekannt sind.
Das Zuweisen einzelnener Eigenschaften lässt es aber nicht zu einen konsistenten Zustand zu garantieren.
Änder ich Eigenschaft1 zu "X" wäre meine Instanz vllt ouchy banana und der Setter springt mir ins Gesicht.
Er kann ja nicht wissen, dass ich Eigenschaft2 direkt danach auch "Y" ändern wollte.
Ein Konstruktor, dem beide Werte übergeben werden, und der sie in einer "Transaktion" ändern kann ist hier natürlich vorteilhaft.
Genau wie es oben genannte Factory wäre.
Zitat:
In seltenen Fällen (siehe TFileStream) kann es aber durchaus Sinn machen (bzw. die Tipparbeit erheblich verkürzen und zu lesbarerem Code führen), Eigenschaften in einem Konstruktor zu übergeben und eine Prüfung während der Instantiierung vorzunehmen.
Selten ist Tipparbeit, sondern Konsistenz die Motivation dahinter.
Zitat:
Dann wird eine
Exception ausgelöst, wie es hier auch schon erwähnt wurde. Es wird -soweit ich weiss- kein Speicher alloziiert, sodaß die Instanz auch nicht freigegeben werden muss.
Der Konstruktor wird nach NewInstance ausgeführt, also nachdem Speicher reserviert wurde.
In der Kette der einzelnen Calls, die irgendwann zu einer fertigen Instanz führen, wird aber beim Auftreten einer
Exception die neue Instanz sofort freigegeben.
Zitat von
Jelly:
Wie Chris schon schrieb, so würd ich das auch lösen. Anstatt einer einfachen
Exception würd ich eventuell eine Assertion auslösen. Denn genau dafür sind die da.
...
Eine Assertion ist eine Art von
exception, die Dir aber bequemerweise aber in der Fehlermeldung auch gleich noch die Zeilennummer in deinem Code ausgibt, in der die Assertion ausgelöst wurde.
Au weia.
Assertions sind dafür da
deinen Code zu prüfen.
Niemals um Dinge zu prüfen, die von außen/ von Benutzern deiner Klasse rein geworfen wurden.
Denn Assertions werden normalerweise im Release ausgeschaltet.