Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Objekterstellung im Konstruktor abbrechen (https://www.delphipraxis.net/54247-objekterstellung-im-konstruktor-abbrechen.html)

Marphy 30. Sep 2005 14:31


Objekterstellung im Konstruktor abbrechen
 
Hallo zusammen,
ich hoffe, dass diese Frage ausnahmsweise mal keine so harte Nuss ist wie meine anderen... :mrgreen:

Also zum Thema:
Ich habe ein Formular mit überschriebenem Create()-Konstruktor, welches dynamisch erstellt wird. Falls eine bestimmte Funktion, die in diesem Konstruktor aufgerufen wird, fehlschlägt (keine Exception, sondern Rückgabewert False), soll die Erstellung des Formulars abgebrochen und es wieder freigegeben werden. Ein Referenz-Parameter im Konstruktor gibt Aufschluss darüber, ob diese bestimmte Funktion fehl schlug oder nicht.

Delphi-Quellcode:
constructor TMyForm.Create(AOwner: TComponent; AMyP: Integer; var ASuccess: Boolean);
begin
  [...]
  if not MyFunc(AMyP) then begin
    Free(); // Oje, das endet böse...
    Exit;
  end;
  [...]
end;
Klar, ich könnte statt Free (was einen bösen Fehler verursacht) eine Exception auslösen und diese beim Create-Aufruf abfangen. Aber ich möchte es einfach eleganter (-> ASuccess)... :???:
Gibt es da einen anderen Lösungsweg?

Ich bin dankbar für jeden Lösungsvorschlag! :-D

Grüße, Marco

P.S.: Damit keiner meckert: :warn: Dieser Beitrag hätte zwar auch ins Forum "VCL / WinForms / Controls" gepasst, da die Frage sich aber eher allgemein auf Objekte als speziell auf "das Formular" bezieht, habe ich sie hier reingestellt.

alzaimar 30. Sep 2005 14:35

Re: Objekterstellung im Konstruktor abbrechen
 
Wieso sind Exceptions nicht elegant?
Delphi-Quellcode:
Try
  anObject := TMyObject.Create;
  anOnject.DoSomeThing;
  anObject.AProperty := FooBar
Except
  Showmessage('Das Objekt konnte nicht erzeugt werden')
End;

Phistev 30. Sep 2005 14:41

Re: Objekterstellung im Konstruktor abbrechen
 
Überschreib TObject.ClassInstance. In der Code-Lib gibt's ein Beispiel (hier) dazu. Einfach die if-Bedingung ändern und evtl. statt raise result:= nil;

@alzaimar: Wenn das Haptprogramm diese Exception dann nicht abfängt...

Sharky 30. Sep 2005 15:02

Re: Objekterstellung im Konstruktor abbrechen
 
Zitat:

Zitat von Phistev
... @alzaimar: Wenn das Haptprogramm diese Exception dann nicht abfängt...

... Hat es genau das selbe Problem als wenn die Variable ASuccess nicht ausgewertet wird ;-)

Die Frage die ich mir stelle: Ist es sinnvoll das mit der Variable zu machen? Immerhin ist es ja fast normal das man mit Try-Except arbeitet.

Oder noch besser gefragt: Was ist der Grund das ich ein Objekt nicht erzeugen kann? Dies sollte ja ein böser Fehler sein und dann finde ich es besser dies mit den Standardmöglichkeiten zu machen.

DerDan 30. Sep 2005 15:23

Re: Objekterstellung im Konstruktor abbrechen
 
oder du machst eine

Class Function CheckAndCreate;

Die dir die Instanz zurückliefert oder auch NIL falls deine Prüfung entsprechendes sagt.

Delphi-Quellcode:
Class Function TMyObj.CheckAndCreate : TMyObj;
begin
  result = TMyObj.Create;
  if not result.Check then
  begin
    freeandnil (result);
  end;
end;
mfg

Der Dan

alzaimar 30. Sep 2005 15:25

Re: Objekterstellung im Konstruktor abbrechen
 
Hi PHistev,
Dein Einwand ist sinnlos. Wer die Exception nicht abfängt wird auch den Flag 'Success' nicht abfragen.

Aber wenn die Exception nicht abgefangen wird, passiert zumindest eins nicht: "Nil Pointer exception"

Deine Variante:
Delphi-Quellcode:
  ...
  MyObject := TMyObject.Create (Success);
  MyObject.DoSomething; // <-- Phatoomp, wenn Success = False,
  ...
Meine Variante:
Delphi-Quellcode:
  ...
  MyObject := TMyObject.Create;
  MyObject.DoSomething; // <-- Wird erst gar nicht ausgeführt, und der Anwender sieht, wie gut der Entwickler ist!
  ...
Frage: Was ist besser? Was ist sicherer? Was führt vielleicht mal zu unangenehmen Effekten?

@DerDan: Noch eine Möglichkeit. Viele Wege führen nach Rom. Aber Dein Weg ist wenigstens gepflastert :zwinker: Hat aber einen Nachteil: Es wird ein illegales Objekt erzeugt. Es kann ja sein, das das Objekt einfach nicht erzeugt werden _kann_ (oder nur mit Schwierigkeiten).

Ich bleib dabei: Mit Exception ist's am einfachsten. Vielleicht sogar mit der ClassFunction von DerDan.

DerDan 30. Sep 2005 15:33

Re: Objekterstellung im Konstruktor abbrechen
 
Zitat:

Zitat von alzaimar
@DerDan: Noch eine Möglichkeit. Viele Wege führen nach Rom. Aber Dein Weg ist wenigstens gepflastert :zwinker: Hat aber einen Nachteil: Es wird ein illegales Objekt erzeugt. Es kann ja sein, das das Objekt einfach nicht erzeugt werden _kann_ (oder nur mit Schwierigkeiten).

Ich bleib dabei: Mit Exception ist's am einfachsten. Vielleicht sogar mit der ClassFunction von DerDan.

Bei einem einfachen Create muss ja noch nichts von dem Aufgerufen werden, was das anlegen verhindert.
Das kann man ja in die Function Check reinlegen.
Von da her seh ich keine Situation bei der man nicht mal erst ein Object anlegen können sollte.

Wird übrigens bei allen anderen Varianten hier in den obigen beispielen auch gemacht

Marphy 1. Okt 2005 16:25

Re: Objekterstellung im Konstruktor abbrechen
 
Hallo zusammen,
danke erstmal für die zahlreichen Antworten... :-D

Nun, zum besseren Verständnis der Situation:
Ich will direkt im Create-Konstruktor des Formulars Daten in selbiges laden. Da dies aber scheitern kann, soll bei einem Fehler die Erstellung der Form abgebrochen werden. Die Funktion zum Laden der Daten verursacht bei Fehlern (normalerweise) keine Exception, sondern gibt den Erfolg über Result zurück.

Die beste Lösung meines Problems ist wohl die Kombination von "Exception" und ASuccess.

Delphi-Quellcode:
constructor TMyForm.Create(AOwner: TComponent; AMyP: Integer; var ASuccess: Boolean);
begin
  ASuccess := False;
  [...]
  if not MyFunc(AMyP) then
    Abort(); // Aha...
  [...]
  ASuccess := True;
end;

[...]
  try
    TMyForm.Create(Self, 123, Success);
  except
    if not ASuccess then
      // Funktion gescheitert
  end;
[...]
Tjaja, diese Abort-Prozedur hat mir gefehlt... :stupid:

Richtig Sinn macht ASuccess zugegebenermaßen eigentlich erst, wenn es über eine Enumeration Aufschluss über den Erfolg bzw. Nichterfolg der Formularerstellung gibt, was sich aber problemlos erweitern lässt.

Viele Grüße,
Marco

alzaimar 1. Okt 2005 18:42

Re: Objekterstellung im Konstruktor abbrechen
 
Ich würde mich mal näher mit Exceptions, bzw. der Programmflusskontrolle beschäftigen. Dann kannst Du ziemlich elegant deine 'Enumeration' vergessen und den Grund des Scheiterns komplett über Exceptions abbilden. Du definierst Dir einfach verschiedene Exceptionklassen, die Du individuell abfangen kannst (steht alles in der OH)
Delphi-Quellcode:
Type
  EWrongParameter = Class (Exception);
  EInvalidUsage = Class (Exception);
...
Constructor TMyObject.Create (aParameter : TSomeType);
Begin
  Inherited;
  If UsageInvalid Then
    Raise EInvalidUsage.Create ('Some Text');
  If Not CheckParameter (aParameter) Then
    Raise EWrongParameter.CreateFmt('Wrong parameter type %s',[aParameter]);
  ...
End;
...

Begin
  Try
    oMyObject := TMyObject.Create;
    oMyObject.CanCallMethods;
  Except
    On E:EInvalidUsage Do
      HandleError;
    On E:EWrongParameter Do
      HandleAnotherError;
   // Alle anderen Fehler (Speicher etc.) werden nicht abgefangen und werden weitergeleitet!
    End;
...
End;
So hast Du eine strikte Trennung im Programm. Der normale Programmfluss ist klar sichtbar und die Fehlerbehandlung ist abgegrenzt.

Marphy 1. Okt 2005 19:30

Re: Objekterstellung im Konstruktor abbrechen
 
Hallo Alzaimar,

Zitat:

Zitat von alzaimar
Ich würde mich mal näher mit Exceptions, bzw. der Programmflusskontrolle beschäftigen. Dann kannst Du ziemlich elegant deine 'Enumeration' vergessen und den Grund des Scheiterns komplett über Exceptions abbilden. Du definierst Dir einfach verschiedene Exceptionklassen, die Du individuell abfangen kannst (steht alles in der OH)
[...]
So hast Du eine strikte Trennung im Programm. Der normale Programmfluss ist klar sichtbar und die Fehlerbehandlung ist abgegrenzt.

Danke für den Hinweis... Du hast schon Recht, wenn man die Möglichkeiten der Exceptions geschickt nutzt, kann das einige Vorteile bringen. Ich werde mich mal eingehender damit beschäftigen, danke nochmal. :)

Gruß, Marco

mschaefer 1. Okt 2005 20:39

Re: Objekterstellung im Konstruktor abbrechen
 
Hallo Marco,

irgendie dreht sich mir der Magen um wenn ich im Creator einen Destroy einleiten soll. Das ist logisch schwierig!
Man könnte natürlich einen Timer erstellen, der bei fehlenden Daten im Timerevent ein Destroy auslöst, aber den für mich korrekten Weg würde ich darin sehen ein Datentestobject die Datenverfügbarkeit testen zu lassen und nach Ergebnis dann das Formular aufzubauen. Das würde auch einiges an Speicherschiebereien sparen, denn Formulare sind doch große Objecte.

Viele Grüße // Martin

alzaimar 1. Okt 2005 21:04

Re: Objekterstellung im Konstruktor abbrechen
 
Hi Martin,

ich bin zwar nicht gemeint, aber ich schalte mich mal zwischen: Ich kann Deinen Einwand zwar nachvollziehen, hier aber nicht sehen. Meine Interpretation eines Konstruktors ist hier, wie der Name schon sagt, eine Aufforderung zum Erzeugen eines Dingens. So, wie z.B. ein Haus bauen.
Ich sage also: "Ich gebe Dir den Auftrag, ein Haus zu bauen, Danke schon mal". Es ist doch legitim, wenn das, aus welchen Gründen auch immer, nicht hinhaut. Das war die Intention von Marco.

Natürlich ist es Quatsch, die grundlegende Prüfung der Vorbedingungen in den Konstruktor zu stopfen. Genauso fatal wäre es, um beim Vergleich zu bleiben, den Auftrag fürs Häusle bauen ohne vorherige Prüfung zu geben.

Jetzt weiss ich auch, worauf Du hinaus willst: Der Konstruktor sollte also nicht das Haus bauen, sondern zunächst, sagen wir, die Absicht manifestieren. Danach erfolgt die Prüfung der Bonität, der Kosten, des Bauträgers etc. Wenn hier was schiefgeht, dann wird der Vorgang eben abgebrochen....

So gesehen, sollte der Konstruktor noch gar keine konkreten Aufgaben übernehmen oder Werte festsetzen, sondern nur die Voraussetzungen schaffen.

Doch, damit kann ich mich anfreunden. Nicht, das ich mir widerspreche, ich plädiere unbedingt für eine Flusskontrolle mit Exceptions (statt ständig irgendwelche Returncodes auszuwerten). Aber das Wesen eines Konstruktors wäre demnach nur die Bereitstellung eines Gerüstes ('Framework'), mit dem man die Aufgabe angehen kann. Der Aufruf des Konstruktors kann schiefgehen, das wäre aber ein GAU, wie Speicher voll, Flasche leer oder so was.

Interessanter Aspekt.

mschaefer 1. Okt 2005 21:36

Re: Objekterstellung im Konstruktor abbrechen
 
N´abend Alzaimar,

ja Deinen Vergleich finde ich gut. Wollte mich in die Diskussion zu den Exception da nicht einmischen.
Habe halt noch nie was im Constructor abgebrochen und da erwarte ich es in meinem Code eigentlich auch nicht.

Grüße // Martin

Robert Marquardt 2. Okt 2005 06:21

Re: Objekterstellung im Konstruktor abbrechen
 
Wenn eine Exception im Konstruktor ausgeloest wird, dann wird automatisch der Destruktor aufgerufen.
Man muss also nur den Code im Konstruktor und Destruktor auf einander abstimmen, da die normale
Implementierung des Destruktors die vollstaendige Initialisierung im Konstruktor annimmt.
Wenn man nun die Erstellung des Objekts in try except einschliesst, dann bekommt man das gewuenschte Ergebnis.

Marphy 2. Okt 2005 16:02

Re: Objekterstellung im Konstruktor abbrechen
 
Hallo zusammen,
da muss ich doch auch noch ein Wörtchen zu sagen...

Zitat:

Zitat von mschaefer
irgendie dreht sich mir der Magen um wenn ich im Creator einen Destroy einleiten soll. Das ist logisch schwierig!
Man könnte natürlich einen Timer erstellen, der bei fehlenden Daten im Timerevent ein Destroy auslöst

Wenn du den zuletzt genannten Weg besser oder gar eleganter findest, ist dir wirklich nicht mehr zu helfen... Bei allem Respekt, aber dieser Vorschlag ist doch überflüssig. :wink:

Zitat:

Zitat von mschaefer
aber den für mich korrekten Weg würde ich darin sehen ein Datentestobject die Datenverfügbarkeit testen zu lassen und nach Ergebnis dann das Formular aufzubauen.

Ja, das geht natürlich. Aber dass z.B. die Datei nicht gelesen werden kann, ist ja nur eine von vielen, vielen möglichen Fehlerquellen, zumal meine Anwendung schon ein wenig komplexer ist als z.B. ein einfacher Texteditor. :roll:

Zitat:

Zitat von mschaefer
Das würde auch einiges an Speicherschiebereien sparen, denn Formulare sind doch große Objecte.

Deine Aussagen ergeben einen einzigen Widerspruch! Was wird wohl mehr "Speicherschiebereien" verursachen: Eine aufwendige Vorprüfung aller nur erdenklichen, möglichen Fehler (welche - o Schreck - auch Festplattenzugriffe erfordern würde :shock:) oder das Abbrechen der Objekterstellung bei einem Fehler.
Was wäre dein "Lösungsweg" nur für eine Ressourcen- und Energieverschendung, wenn man bedenkt, dass vielleicht bei 100 Versuchen ein einziges Mal ein Fehler auftritt? Alle Prüfungen umsonst... Da dreht es mir den Magen um! :pale:

Zitat:

Zitat von alzaimar
ich bin zwar nicht gemeint, aber ich schalte mich mal zwischen: Ich kann Deinen Einwand zwar nachvollziehen, hier aber nicht sehen. Meine Interpretation eines Konstruktors ist hier, wie der Name schon sagt, eine Aufforderung zum Erzeugen eines Dingens. So, wie z.B. ein Haus bauen.
Ich sage also: "Ich gebe Dir den Auftrag, ein Haus zu bauen, Danke schon mal". Es ist doch legitim, wenn das, aus welchen Gründen auch immer, nicht hinhaut. Das war die Intention von Marco.

Danke für die schützende Stellungnahme! :-D

Zitat:

Zitat von alzaimar
Jetzt weiss ich auch, worauf Du hinaus willst: Der Konstruktor sollte also nicht das Haus bauen, sondern zunächst, sagen wir, die Absicht manifestieren. Danach erfolgt die Prüfung der Bonität, der Kosten, des Bauträgers etc. Wenn hier was schiefgeht, dann wird der Vorgang eben abgebrochen....

So gesehen, sollte der Konstruktor noch gar keine konkreten Aufgaben übernehmen oder Werte festsetzen, sondern nur die Voraussetzungen schaffen.

Ich stopfe das Ganze doch nicht aus Spaß gerade in den Konstruktor. :roll:
Warum hätte es ein OnCreate()-Handler denn nicht auch getan? Weil bei einem auftretenden Fehler der Aufbau des Formulars nicht einfach wieder abgebrochen werden könnte (oder hat da jemand eine Idee?). Und es würde auch keinen Sinn machen, das nackte Formular ohne Daten vor sich zu haben...

Zitat:

Zitat von alzaimar
Doch, damit kann ich mich anfreunden. Nicht, das ich mir widerspreche, ich plädiere unbedingt für eine Flusskontrolle mit Exceptions (statt ständig irgendwelche Returncodes auszuwerten). Aber das Wesen eines Konstruktors wäre demnach nur die Bereitstellung eines Gerüstes ('Framework'), mit dem man die Aufgabe angehen kann. Der Aufruf des Konstruktors kann schiefgehen, das wäre aber ein GAU, wie Speicher voll, Flasche leer oder so was.

s.o. (Man beachte, das ein Formular oder Control anders zu handhaben ist als eine einfache Klasse.)

Zitat:

Zitat von mschaefer
Habe halt noch nie was im Constructor abgebrochen und da erwarte ich es in meinem Code eigentlich auch nicht.

Man sollte halt nicht immer nur von sich ausgehen... :mrgreen: :wink:

@Robert:
Jaja, das ist mir schon klar. Dies schrieb ich ja bereits im "Root Posting". :stupid:

Liebe Grüße, Marco

P.S.: Ich wollte hier niemanden auf irgendeine Weise angreifen oder runtermachen. Außer den Smilies kann man in ein Posting ja keinerlei Emotionen mit reinpacken, welche in einem Gespräch aber alles andere als unwichtig sind. :nerd: Das nur nebenbei bemerkt... :zwinker:

mschaefer 2. Okt 2005 16:48

Re: Objekterstellung im Konstruktor abbrechen
 
Moin, moin,


In Alzaimar Beispiel findet sich im Creator das inherited am Procedureanfang. Dadurch durchläuft das Object Formular schon einiges an Allocations und Aufbauarbeit und nur die letzte Instanz ist noch nicht geklärt, das bestätigt den Speicherhinweis, da beisst die Maus kein Faden ab.

Sind Deine Prüfungen für mehrer Formulare eher gleichlaufend, dann würde ich meine Vorobjectmethode nicht wegwerfen. Zumahl Du wahrscheinlich eine zentrale Aufrufroutine haben wirst, wo die Formulare dynamisch aufgebaut werden, je nach Anwahl des Nutzers.

Sind die Prüfungen sehr Formularspezifisch sehe ich auch, dass die Constructor-Variante, (ja für mich was Neues, her damit) der übersichtlichere Weg ist, da alle Aufgaben in der Formularunit liegen, ok, klingt logisch, macht Sinn! -> Mach es so !


Uhps schon wieder Teatime, ja man hat so seine Verpflichtungen... -:)


Viele Grüße // Martin




// PS: Texteditoren mit vielen dynamischen Formularen sind ein Fall für den Papierkorb... //

Marphy 2. Okt 2005 17:00

Re: Objekterstellung im Konstruktor abbrechen
 
Hallo Martin,
wenn du deine Prüfungs-Methode überzeugend verteidigen willst, darfst du meinen entsprechenden Nachfragen nicht einfach ausweichen... :wink:

Zitat:

// PS: Texteditoren mit vielen dynamischen Formularen sind ein Fall für den Papierkorb... //
Aha, wieso das? :gruebel:

Gruß, Marco

mschaefer 2. Okt 2005 18:18

Re: Objekterstellung im Konstruktor abbrechen
 
Hi Marco,
sorry, der Computer darf heute leider nicht dauernd laufen...

Ja ok, ein Texteditor ist für mich keine Textverarbeitung oder IDE.
Sowas mag ich klein handlich und ohne viel Schnickschnack um eben mal eine Text zu edieren: halt Notepad und gut...


Wer sich schon über der die dynamische Verwaltung seiner Formulare Gedanken macht, programmiert daher mit hoher Wahrscheinlichkeit an etwas komplexeren, das liegt jedenfalls nahe. Das Thema dynamische Formulare ist für mich
interessant, da ich schon des längerem an einem MDI-System arbeite, wo Teile des MDI-Formulars noch sichtbar sind und die Clients je nach Funktion eingeblendet werden und die Tastatursteuerung natürlich über die Formulargrenzen erhalten bleiben muß. Also man kann mit sowas viel Zeit verbringen.

An einer Sache bin ich bisher leider auch immer noch gescheitett: Eignetlich wollte ich eine Komponente bauen, wo ich alle in frage kommenden Formulare als Liste lade. Die Komponente sollte dann nur Namen oder Nummer des Formulars bekommen, andere dann schließen und das entsprechende öffnen. Aber leider ist das daran gescheitert, das ich ja verschieden Objectypen erstellen muß und die habe ich bis daher nich in die Listenverwaltung bekommen. Na da geht wohl noch Wasser die Leine herunter....

Grüße // Martin

alzaimar 3. Okt 2005 07:28

Re: Objekterstellung im Konstruktor abbrechen
 
Ich kann mir ganz gut vorstellen, das beide Verfahren zu stabilen und übersichtlchem Code führen.
Der eine prüft eben explizit, der Andere geht das Risko ein, das die Karre gegen die Wand fährt, und räumt hinterher auf. Ich kann mich für beide Verfahren erwärmen, die Hauptsache ist doch, das man weiss, was man tut und das das Ergebnis stabil, übersichtlich und wartbar wird.

Wenn ich eine vollständige Fallunterscheidung hinbekomme, unter welchen Umständen etwas schiefgehen könnte, dann implementiere ich das. Wenn nicht, dann wird mit Try....Except gearbeitet. Nur Rückgabewerte à la 'aSuccess', die zeigen, ob etwas schiefgegangen ist, verkneife ich mir normalerweise, weil sie eben aus einer Folge von Anweisungen If..Then Anweisungen machen.

@mschaefer: Dein Problem hatte ich mal mit einem Pagecontrol (HideTabs=True) und einer Basisklasse (TModule, abgeleitet von TForm) gelöst, die in der Lage ist, sich auf einem TabSheet zu plazieren (Parent umbiegen). Das Hin-und-Herschalten geschieht über PageControl.ActivePageIndex. Auf einem TModule-Formular kann ich Actionlists definieren, die mit der Actionlist des MDI-Masters beim Modul-Umschalten verschmolzen werden: Ich habe so eine Grundfunktionalität, die über alle Module hin identisch sind, sowie für jedes Modul individuelle Aktionen, die nur dann sichtbar werden, wann das entsprechende Modul aktiviert ist.

Flocke 3. Okt 2005 09:28

Re: Objekterstellung im Konstruktor abbrechen
 
... und schließlich noch mein Senf :mrgreen:

IMHO ist in so einem Falle die Prüfung bei der Erstellung immer sinnvoller als vorher einen vielleicht aufwändigen Test durchzuführen. Wer garantiert mir denn, dass es trotz vorheriger Prüfung klappt? Niemand!

Wenn du z.B. mit FileExists vorher prüfst, ob eine Datei existiert, dann kann es im Konstruktor dennoch sein, dass du sie nicht öffnen kannst (keine Rechte, Sperrung, etc.).

Auch kann z.B. ein Datensatz, den du vor dem Aufruf von Create überprüft hast, im Konstruktor schon wieder gelöscht sein.

Was habt ihr denn alle gegen Exceptions???

Was ist sooo schlimm daran, dass eine Box mit "Es eine Ausnahmebedingung vom Typ BlaBlaBla aufgetreten" kommt anstatt eurer eigenen Box mit "ich konnte die Datei nicht öffnen"?

Auf Exceptions muss man immer vorbereitet sein, denn unvorhersehbare Ausnahmebedingungen können immer auftreten. Und wenn man dieses Konzept sauber durchzieht, dann braucht man keine Vorab-Checks mehr!

mschaefer 3. Okt 2005 09:50

Re: Objekterstellung im Konstruktor abbrechen
 
Moin, moon

ja die Exceptions stehen derzeit wohl als geeignet fest. Da hat es von keinem nennenswerte Kritik gegben. Beim Thema Vorabprüfung (durchaus mit Exception) oder Prüfung im Creator zeichnet sich ja ein Muster ab. Einen Aspekt mag ich nochmal einwerfen. Für den Anwender ist es natürlich günstig, wenn er sieht ob eine Funktion verfügbar ist. Also wenn ein Menüpunkt zu einem Formular aktiv ist oder inaktiv. Für diesen wäre es natürlich günstig, wenn bei Aufruf des Menues geprüft wird. Das schließt natürlich eine Überprüfung im Creator für aufwendigere Prüfungen nicht aus.

Grüße // Martin

Robert_G 3. Okt 2005 09:53

Re: Objekterstellung im Konstruktor abbrechen
 
Zitat:

Zitat von Flocke
Und wenn man dieses Konzept sauber durchzieht, dann braucht man keine Vorab-Checks mehr!

Ganz so extrem würde ich es nicht ausdrücken...
Eine Exception auszulösen kostet schließlich auch etwas crunch time. ;)
Aber generell ist es logisch, dass eine Klasse, die im Konstruktor einen Dateinamen will, diese auch öffnen will.
Weiter ist es logisch, dass es knallt wenn die Klasse mit der Datei nicht das machen kann, was sie will.
Das sollte für die meisten auch nix neues sein... Schließlich dürfte hier jeder schonmal eine Instanz eines FileStream erzeugt haben. :zwinker:
Ich verstehe nur nicht ganz (eigentlich üerhaupt nicht) warum man das in eine Form-Ableitung stopfen will.
Das ist so flexibel wie ein Hummer auf der Go Cart-Bahn oder ein Navi, dass fest mit dem Rahmen verschweißt ist, so dass man sich ein neues Auto bauen muss um die jährliche Update DVD verwenden zu können...

Flocke 3. Okt 2005 10:04

Re: Objekterstellung im Konstruktor abbrechen
 
Zitat:

Zitat von Robert_G
Zitat:

Zitat von Flocke
Und wenn man dieses Konzept sauber durchzieht, dann braucht man keine Vorab-Checks mehr!

Ganz so extrem würde ich es nicht ausdrücken...

Die überzogene Ausdrucksweise war durchaus Absicht! :zwinker:

Zitat:

Zitat von Robert_G
Eine Exception auszulösen kostet schließlich auch etwas crunch time.

In dem Fall kann man das wohl vernachlässigen, weil das langsamste der User bei Drücken auf den OK-Knopf im Fehlerdialog sein wird...

mschaefer 3. Okt 2005 10:18

Re: Objekterstellung im Konstruktor abbrechen
 
Moin,

Vom Prinzip her wäre es natürlich schon richtiger die Funktionalität von der Anzeige zu trennen und da sehe ich Roberts Kritik das in den Formularcreator zu legen. Das Problem ist aber durch die VCL eigentlich nicht wirklich lösbar.

Grüße // Martin

alzaimar 3. Okt 2005 11:06

Re: Objekterstellung im Konstruktor abbrechen
 
Zitat:

Zitat von Robert_G
Aber generell ist es logisch, dass eine Klasse, die im Konstruktor einen Dateinamen will, diese auch öffnen will.

Nö, ist gar nicht logisch. Beispiel:
Delphi-Quellcode:
Type
  TFileTool = Class (TSomething)
  ...
  Public
    Constructor Create (aFileName : String);
    Procedure OpenForRead;
    Procedure OpenForWrite;
    Procedure CreateFile;
    Function FileSize : Integer;
    ....
  End;
Der Konstruktor macht noch gar nichts. Er weiss doch nicht, was ich mit dem Parameter anstellen will.

Ich würde hier überhaupt keine Regeln festsetzen, ob man im Konstruktor alles abchecken soll, oder nicht. Es ist eine Frage der Herangehensweise. Was IST das Objekt? Wozu ist es da? Danach richtet sich dann, was der Konstruktor machen sollte. In meinem fiktiven Beispiel instantiiert der bloss das Objekt und schreibt von mir aus den Parameter in ein privates Feld. Das wars dann aber. Man könnte hier z.B. nur prüfen, ob der Name gültig ist, oder nicht. Aber wenn ich den Namen später austauschen kann, dann bringt das auch nicht viel, weil die Gültigkeit des Parameters beim Konstruktor doch noch gar keine Rolle spielt.

Beim Konstruktor eines Formulars wird ja ne ganze Menge angestellt (Handles holen etc.). Da würde ich mir schon überlegen, ob da nicht mal eine Überprüfung nach dem Motto "Can I Create it?" nicht doch sinnvoll wäre. Aber, wie Flocke schon erwähnte, und was durch die Murphyschen Grundregeln ('If it can go wrong, it WILL go wrong') manifestiert ist, Exceptions lauern überall.

Ich kann natürlich Exceptions auch anders interpretieren, nämlich als 'Ausnahme'. Sind sinnlose Parameter dann Ausnahmen? Oder sind Ausnahmen wirkliche Programm(ier)fehler, die die Kacke zum Dampfen bringen? Das sei doch jedem selbst überlassen. Ich finde, man sollte sich darüber Gedanken machen, und die Linie dann mehr oder weniger durchziehen. Denn ein Programm wird umso übersichtlicher und stabiler, je orthogonaler ich meine (Programmier-) Philosophie und Interpretation dort einfliessen lasse. Dann weiss ich, das eine Exception ein GAU ist, IMMER (oder eben nicht, je nach Philosophie).

Es ist immer eine Frage des Geschmacks, wie ich meine Flusskontrolle realisiere. So hat z.B. die Rückgabe von Statuswerten auch seine Berechtigung, nämlich dann, wenn ich mich nicht immer drum scheren muss, ob es nun geklappt hat, oder nicht. Bei einem Konstruktor ist das natürlich selten sinnvoll, weil ich i.A. noch etwas mit dem Objekt anstellen will.

Marphy 4. Okt 2005 19:01

Re: Objekterstellung im Konstruktor abbrechen
 
Hallo zusammen,
danke für die interessante Diskussion. :)

Ich würde sagen, es ist abhängig von der Situation, wie man das Ganze nun realisiert. In meinem Falle (den ich in den vorherigen Postings ja wirklich schon zu genüge beschrieben habe ;) ) ist der beste Weg die Exceptions, wie gesagt. Sicher, man könnte (sicherheitshalber) noch triviale Vorprüfungen wie z.B. FileExists() vorneanhängen. Aber wie gesagt, ein solcher Festplattenzugriff ist wahrscheinlich noch langsamer als ein gescheiterter Formularaufbau... Aber wir drehen uns glaube ich im Kreis. :D

Zitat:

Zitat von alzaimar
Denn ein Programm wird umso übersichtlicher und stabiler, je orthogonaler ich meine (Programmier-) Philosophie und Interpretation dort einfliessen lasse.

Aha. :nerd: :gruebel: :wink:

Gruß, Marco

alzaimar 5. Okt 2005 09:59

Re: Objekterstellung im Konstruktor abbrechen
 
Zitat:

Zitat von Marphy
Zitat:

Zitat von alzaimar
Denn ein Programm wird umso übersichtlicher und stabiler, je orthogonaler ich meine (Programmier-) Philosophie und Interpretation dort einfliessen lasse.

Aha. :nerd: :gruebel: :wink:
Gruß, Marco

Was ich damit sagen will, ist das die inharene Transubtraktionsintoxokarthinartransestenz als Kernstück einer zukunftsweisenden Technologie diktional kontraindiziert. :warn:

Oder, anders ausgedrückt: Wenn ich weiss, was und wie ich programmiere (also meinen Stil durchziehe), dann werden Programme automatisch stabil(er) und wartbar(er).

Oder, noch anders ausgedrückt: Erst planen, dann coden.

Marphy 5. Okt 2005 10:58

Re: Objekterstellung im Konstruktor abbrechen
 
Hallo alzaimar,
ok, jetzt hab ich's verstanden... :shock: :wink:

Gruß, Marco

tigerman33 5. Okt 2005 14:27

Re: Objekterstellung im Konstruktor abbrechen
 
Zitat:

Zitat von alzaimar
Was ich damit sagen will, ist das die inharene Transubtraktionsintoxokarthinartransestenz als Kernstück einer zukunftsweisenden Technologie diktional kontraindiziert.

:shock: Wow! Wo lernt man denn solche Sätze zu bilden?

Ob ich dir in der Sache zustimme, bin ich mir aber nicht ganz sicher. An "erst denken, dann coden" besteht zwar nicht viel Zweifel, aber IMHO nur insofern sich das auf die Sachfragen bezieht. Solange die sauber gelöst werden, ist der Stil, denke ich, mehr oder weniger egal.

Marphy 5. Okt 2005 14:47

Re: Objekterstellung im Konstruktor abbrechen
 
Hallo zusammen,
okay, da wir nun mehr oder weniger vom bereits gelösten Thema abkommen, ist es denke ich nun an der Zeit, diesen Thread offiziell als erledigt zu kennzeichnen.
(Solch einen Button sollte nicht nur bei "offenen Fragen" geben :warn:).

Ich danke euch für die interessante Diskussion! :thumb:

Bis auf bald,
Marco

P.S.: Ach ja, vielleicht könntet ihr mal schnell im VCl/Controls-Forum vorbeischauen? :lol: Da ist leider noch so eine "dumme" Frage von mir offen und wir/ich komme(n) einfach nicht weiter... :cry:


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:39 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz