Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Rückgabewert für Login-Funktion? (https://www.delphipraxis.net/116211-rueckgabewert-fuer-login-funktion.html)

Yheeky 25. Jun 2008 07:12


Rückgabewert für Login-Funktion?
 
Hi,

ich habe eine Klasse und mit der Funktion "Login". Hier möchte ich nicht nur den Rückgabewert true oder false für Erfolg oder Misserfolg zurückgeben, sondern verschiedene "Fehlermeldungen" (z.B. falsches Passwort, nicht vorhandener Benutzername). Wie kann ich das am besten realisieren?

Zur Zeit sieht mein Funktionskopf so aus:

Delphi-Quellcode:
function Login : Boolean;
Könnte natürlich einen Rückgabewert wie Cardinal benutzen und die Fehlermeldungen durchnummerieren, aber das ist sicherlich nicht die beste Lösung, oder?

Wäre super, wenn mir jemand einen Tipp geben kann.

DeddyH 25. Jun 2008 07:16

Re: Rückgabewert für Login-Funktion?
 
Die erste Möglichkeit hast Du ja schon angesprochen (wobei ich persönlich diese am Besten finde). Ein zweite wäre z.B.
Delphi-Quellcode:
function Login(var sMeldung: string): Boolean;
In sMeldung wird dann der entsprechende String hineingeschrieben.

Medium 25. Jun 2008 08:05

Re: Rückgabewert für Login-Funktion?
 
Für so etwas nehme ich sehr gerne Aufzählungen her.

Etwa:
Delphi-Quellcode:
type
  TLoginResult = (lrOK, lrErrorWrongPW, lrErrorUserUnknown, ...);
.
.
  function Login: TLoginResult;
Und dann mit case im Aufrufer hantieren - idealerweise noch resourcestrings dort einsetzen.


Wann immer möglich, vermeide ich Rückgaben über die Parameter, aber auch nur, weil ich es aus logischen Gründen als für "nicht sehr elegant" empfinde. Das hat aber keine technischen Gründe.

RavenIV 25. Jun 2008 08:07

Re: Rückgabewert für Login-Funktion?
 
Also ich würde es so machen, wie bei MessageDlg.
Da wurden Konstanten mrYes, mrNo, mrCancel, usw definiert und einfach durchnummeriert.
Die Funktion MessageDlg gibt dann eine der Konstanten zurück.
über den Konstantennamen kannst Du auf vernünftige Weise darauf zugreifen.
Du hast also nicht "3" als Rückgabe, sondern lrPwdError oder so ähnlich.

Das wird bei Windows auch nicht anderst gemacht.
Seien das nun Windows-Messages, irgendwelche Fehlercode oder sonst was.

Und der grösste Vorteil:
Du kannst dann mit case..of arbeiten, was Du bei Strings nicht kannst.

Man kann dann ja noch zusätzlich als out-Parameter einen Result-Text verwenden.

Yheeky 25. Jun 2008 14:19

Re: Rückgabewert für Login-Funktion?
 
Genau so habe ich es jetzt gemacht 8)
DANKE!

OregonGhost 25. Jun 2008 15:27

Re: Rückgabewert für Login-Funktion?
 
Mal als neugierige Frage an alle: Was spricht gegen eine Exception im Fehlerfall?

RavenIV 25. Jun 2008 15:32

Re: Rückgabewert für Login-Funktion?
 
Zitat:

Zitat von OregonGhost
Mal als neugierige Frage an alle: Was spricht gegen eine Exception im Fehlerfall?

Dagegen spricht, dass es ein kalkulierbarer "Fehler" ist und beeinflussbar ist.
Hier ist eine Exception fehl am Platz.

Ausserdem wäre das zu viel Overhead.
- Einige Exceptions definieren(EPasswortFalsch, EUserFalsch, E...)
- entsprechende Exception werfen
- Exceptions auffangen
- Exception auswerten und entsprechend reagieren

OregonGhost 25. Jun 2008 16:08

Re: Rückgabewert für Login-Funktion?
 
Zitat:

Zitat von RavenIV
Dagegen spricht, dass es ein kalkulierbarer "Fehler" ist und beeinflussbar ist.
Hier ist eine Exception fehl am Platz.

Ausserdem wäre das zu viel Overhead.
- Einige Exceptions definieren(EPasswortFalsch, EUserFalsch, E...)
- entsprechende Exception werfen
- Exceptions auffangen
- Exception auswerten und entsprechend reagieren

Verstehe ich ehrlich gesagt nicht. Beim Anlegen einer Datei ist ein Schreibschutz, Platte voll o.ä. auch ein kalkulierbarer Fehler, der gar nicht so selten ist, wie man vielleicht denkt, ebenso beim Öffnen einer Datei.
- Statt Exceptions definierst du lauter Konstanten.
- Statt Exceptions zu werfen, gibst du Konstanten zurück.
- Statt Exceptions aufzufangen, musst du die verschiedenen Fälle einzeln auswerten (es gibt keine eventuelle Klassenhierarchie wie bei Exceptions, die das Handling vereinfachen, z.B. IOException als Oberbegriff).
- Eventuelle Fehlermeldungen musst du explizit überall bereitstellen, wo die jeweilige Funktion aufgerufen wird.

Und der Overhead, naja, wie oft pro Sekunde wird eine Funktion "Login" aufgerufen?

Ich will hier nichts in Frage stellen. Aber mich interessiert doch die Rationalität, die ich hier nicht wirklich sehe, mit der hier (in diesem Beispiel, nicht in der DP allgemein ;)) so kategorisch Fehlermeldungen gegenüber Exceptions bevorzugt werden. Für mich ist eine Funktion Login, was immer diese nun genau macht, ein klassisches Beispiel für einen vorwärtsgerichteten Programmablauf - entweder ist, im Idealfall, alles in Ordnung, oder man muss einen Fehler behandeln, soweit möglich. Wenn man erfolgreich durch ist, muss man die Funktion nicht noch einmal aufrufen - im Fehlerfall vermutlich schon, wenn man sich davon Erfolg verspricht. Da hätte ich persönlich jetzt eine Exception eingesetzt, in dessen Handler man eben den erneuten Versuch vorbereitet. Je nach Fehler kann man diesen Fehler dann auch relativ unproblematisch an übergeordnete Routinen weiterreichen.
Ich meine, ich höre auch gelegentlich von einigen C++-Programmierern, die soviel Angst vor dem Overhead von Exceptions haben, dass ihr Code früher oder später nur noch ein Wust von Fehlerüberprüfungen ist, aber Delphiprogrammierer neigen doch eigentlich nicht zu sowas :)
Jedenfalls, in so einem Fall würde ich die Exception einfach vorziehen. Der Code, weder in der Funktion noch der aufrufende, wird dadurch nicht komplizierter, potenziell wird die Behandlung an dieser Stelle (oder, wichtiger, darüber) sogar einfacher und übersichtlicher.

Falls diese Diskussion nicht hierher passt (naja, irgendwie passt sie relativ gut zur Frage), Antworten gerne auch per PN.

shmia 25. Jun 2008 16:09

Re: Rückgabewert für Login-Funktion?
 
Zitat:

Zitat von Yheeky
sondern verschiedene "Fehlermeldungen" (z.B. falsches Passwort, nicht vorhandener Benutzername).

Wobei du dem Benutzer und besonders dem Hacker nie verraten solltest, woran genau der Login gescheitert ist.
Man sollte nur eine ganz allgemeine Meldung ala
"Benutzer / Passwort falsch oder Benutzer wurde gesperrt" oder
"Your account may be disabled or blocked or the username/password you entered is incorrect"
ausgeben.
Und zusätzlich vor der Meldung einen Sleep(1500) einlegen um Brute-force Angriffe zu verhindern.
Von daher braucht auch der Rückgabewert nicht so detailiert sein und es reicht im Prinzip ein Boolean.
Zum Debuggen aber vielleicht doch ganz nützlich.

OregonGhost 25. Jun 2008 16:11

Re: Rückgabewert für Login-Funktion?
 
Zitat:

Zitat von shmia
Zum Debuggen aber vielleicht doch ganz nützlich.

Nur zum Debuggen reicht speziell bei der von dir beschriebenen Vorgehensweise vermutlich auch ein Logeintrag.

sirius 25. Jun 2008 17:07

Re: Rückgabewert für Login-Funktion?
 
Zitat:

Zitat von RavenIV
- Exceptions auffangen
- Exception auswerten und entsprechend reagieren

Muss man evtl. nicht einmal machen. Sofern die Loginfunktion auf eine Useraktion folgt (ButtonClick, MenuClick, etc.) wird die Fehlermeldung sauber nach außen durchgereicht und schön angezeigt. Und das PRogramm läuft ordnungsgemäß weiter. Der User weiß, dass er das Login wiederholen muss.

Medium 26. Jun 2008 02:09

Re: Rückgabewert für Login-Funktion?
 
Exception = Ausnahme. An und für sich ist das eine philosophische Frage, aber man könnte es evtl. so sagen: Exceptions verwende ich, wenn auf Grund des aufgetretenen Fehlers ein stabiles Weiterlaufen der Methode nicht mehr möglich ist, bzw. die Funktion nicht mehr gewahrt ist - also der Zustand nach Auftreten undefiniert ist. Das Exceptionshandling kümmert sich dann um eine saubere Rückkehr aus dem Call, und informiert den Aufrufer darüber, dass eine Situation aufgetreten ist, die nicht sein darf/kann.
Im Falle einer Login-Funktion, die es eben zur Aufgabe hat zu prüfen ob die Daten gültig sind, ist der Fall der Ungleichheit wohl definiert, und keine "Ausnahme", sondern ein erwartetes mögliches Ergebnis, und der Programmfluss wird keineswegs kompromitiert. Von daher würde ich in diesem Fall nicht einmal auf die Idee kommen, Exceptions einzusetzen.

Etwas anderes ist es, wenn z.B. mit einem String aus einer Datei verglichen werden soll, die Datei aber nicht existiert. Hier ist das erwartete Verhalten: Datei ist da, String ist drin, so wirds schließlich ausgeliefert. In dem Fall ist eine Ausnahme eingetreten, zumal es die Gesamtfunktion nachhaltig beeinflusst: KEIN Login kann mehr funktionieren - Prinzipbedingt, nicht weil der User falsche Daten eingegeben hat (was man durchaus erwarten kann), sondern weil etwas unerwartetes passiert ist.
Aber auch das ist imho eigentlich noch zu "weich" für eine Exception. Typische Fälle sind da eher Griffe in Speicherbereiche ausserhalb jeglicher Range, Stackoverflows, defekte Hardware usw.. Das meiste andere ist in definierten Zuständen behandelbar.

Oftmals sind die Messages der Exceptions auch für den Kunden nicht aussagekräftig. Daher würde ich auch niemals eine Exception "einfach so" durchflutschen lassen, sondern zumindest einen generellen Handler machen, der genau beschreibt was wobei nicht geklappt hat, und zwar funktional, damit der User einen Bezug dazu hat - mit technischem Blabla hat der ja meist nichts zu tun - und hänge die Exception-Message daran an, damit er bei einer Supportanfrage auch den technisch relevanten Teil durchgeben kann.
Man stelle sich vor Otto zu sein, und darf auf einmal lesen "Listeninxed überschreitete das Maximum (-1)", als man versucht eine mp3-Datei in seinen Player zu Drag-und-Droppen. Für Otto total nutzlos.

RavenIV 26. Jun 2008 07:53

Re: Rückgabewert für Login-Funktion?
 
Zitat:

Zitat von Medium
Exception = Ausnahme.
<Text gekürzt>

Ich bin 100% genau der gleichen Meinung.

OregonGhost 26. Jun 2008 12:08

Re: Rückgabewert für Login-Funktion?
 
@Medium: Ich verstehe deine Argumentation. Aber, und auch das ist natürlich philosophisch, du beschreibst die Nutzung von Exceptions ausschließlich für unerwartete Fehler. Jedoch ist eine Exception, die man abfängt, nicht unerwartet - im Gegenteil, wenn man zum Beispiel einmal FxCop über ein Programm laufen lässt, wird der sich beschweren, wenn man einen allgemeinen Exception-Handler gebaut hat - weil man damit einen unerwarteten (!) Fehler abfängt, obwohl man nicht weiß, wie er zu behandeln ist. Fängt man jedoch eine spezifische Exception, erwartet man sie ja und kann damit umgehen (und sei es im schlimmsten Fall nur eine Fehlermeldung). Kann man es nicht, fängt man sie eben nicht oder wirft sie weiter.

Zitat:

Im Falle einer Login-Funktion, die es eben zur Aufgabe hat zu prüfen ob die Daten gültig sind, ist der Fall der Ungleichheit wohl definiert, und keine "Ausnahme", sondern ein erwartetes mögliches Ergebnis, und der Programmfluss wird keineswegs kompromitiert. Von daher würde ich in diesem Fall nicht einmal auf die Idee kommen, Exceptions einzusetzen.
Ich stimme damit sofort überein, wenn die Login-Funktion nur die Gültigkeit prüfen soll - wenn sie jedoch auch noch den tatsächlichen Login-Vorgang durchführen soll, ähnelt sie von ihrer Art her eher einer FileOpen-Funktion, und man muss sich drüber streiten, ab wie häufigem Auftreten ein Fehlerfall eine Ausnahme ist oder nicht. Das ist mir zu mühselig. Wo ist eine Ausnahme definiert? Sie tritt in maximal 0,1% aller Fälle auf? Und was, wenn jetzt meine Login-User nur jedes zweitausendste Mal ein falsches Passwort eingeben, deine jedoch jedes fünfhundertste mal? Müssen wir dann unsere Fehler deshalb unterschiedlich behandeln? Das will mir nicht in den Kopf. Oh, und ist so auch nicht ganz ernst gemeint, keine Sorge. ;)
Ich finde nur, eine Login-Funktion hat die Funktion, einen Login durchzuführen - klappt das nicht, ist das schon irgendwie eine Ausnahme. Aber da genau drehen wir uns wieder im Kreis, es ist eine Definitionsfrage. Ich nehme eure Argumentation einfach einmal auf und denke das nächste mal drüber nach, wenn ich in so eine Situation komme.
Hängt das vielleicht auch ein bisschen an der jeweiligen Umgebung, die man verwendet? In C++ zum Beispiel ist es in der STL auch unüblich, Exceptions zu werfen, oder es gibt teilweise Operationen doppelt (einmal mit Fehlercode und einmal mit Exception), und auch Qt kommt weitgehend ohne aus. In Java oder .NET sieht man Exceptions hingegen überall.

marabu 26. Jun 2008 13:35

Re: Rückgabewert für Login-Funktion?
 
Hi,

Zitat:

Zitat von OregonGhost
Mal als neugierige Frage an alle: Was spricht gegen eine Exception im Fehlerfall?

unabhängig vom Thread-Kontext: Das Kriterium für das Werfen einer Ausnahme ist nicht die relative Wahrscheinlichkeit für das Eintreten einer speziellen Fehlersituation, sondern die Frage, ob du diese Situation an der Stelle des Auftretens behandeln willst und kannst.

Freundliche Grüße


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:02 Uhr.

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