5 Stimmen

Gemeinsame Bibliotheksfunktionen verbessern oder aufgeben?

Stellen Sie sich vor, ich habe eine Funktion, die einen Fehler enthält:

Pseudocode:

void Foo(LPVOID o)
{ 
   //implementation details omitted
}

Das Problem ist, dass der Benutzer die null :

Object bar = null;

...

Foo(bar);

Dann wird die Funktion könnte wegen einer Zugriffsverletzung abstürzen; es kann aber auch passieren, dass sie gut funktioniert. Der Fehler besteht darin, dass die Funktion debe auf den ungültigen Fall der Übergabe von null aber es hat einfach nicht geklappt. Es war nie ein Thema, weil man den Entwicklern zutraute, dass sie wussten, was sie taten.

Wenn ich nun die Funktion ändere in:

Pseudocode:

void Foo(LPVOID o)
{
   if (o == null) throw new EArgumentNullException("o");

   //implementation details omitted
}

dann werden Leute, die die Funktion gerne benutzt haben und zufällig keine Zugriffsverletzung erhalten haben, jetzt plötzlich eine EArgumentNullException .

Soll ich weiterhin zulassen, dass Leute die Funktion missbräuchlich verwenden, und eine neue Version der Funktion erstellen? Oder verbessere ich die Funktion so, dass sie das enthält, was sie ursprünglich hätte enthalten sollen?


Und nun das moralische Dilemma. Wollen Sie immer neue Plausibilitätsprüfungen, Sicherheitsprüfungen und Assertions zu bestehendem Code hinzufügen? Oder rufen Sie die alte Funktion auf, die aufgegeben wurde, und haben eine neue?


Nehmen wir einen Fehler, der so häufig auftritt, dass Microsoft ihn für Entwickler beheben musste:

 MessageBox(GetDesktopWindow, ...);

Nie und nimmer, immer ein Fenstermodell auf dem Desktop erstellen möchten. Sie werden das System sperren. Lassen Sie die Entwickler weiterhin den Computer des Benutzers sperren? Oder ändern Sie die Funktion in:

 MessageBox(HWND hWndParent, ...)
 {
    if (hWndParent == GetDesktopWindow)
       throw new Exception("hWndParent cannot be the desktop window. Use NULL instead.");

    ...
 }

In Wirklichkeit hat Microsoft den Fenstermanager so geändert, dass der fehlerhafte Parameter automatisch korrigiert wird:

 MessageBox(HWND hWndParent, ...)
 {
    if (hWndParent == GetDesktopWindow)
       hWndParent = 0;

    ...
 }

In meinem erfundenen Beispiel gibt es keine Möglichkeit, die Funktion zu patchen - wenn mir kein Objekt gegeben wurde, kann ich nicht tun, was ich an ihm tun muss.

Besteht die Gefahr, dass bestehender Code durch Hinzufügen einer Parametervalidierung beschädigt wird? Lassen Sie zu, dass der bestehende Code weiterhin falsch ist und falsche Ergebnisse liefert?

0voto

Synetech Punkte 9247

Das hängt ganz von Ihnen, Ihrer Codebasis und Ihren Benutzern ab.

Wenn Sie Microsoft sind und einen Fehler in Ihrer API haben, der von Millionen von Entwicklern auf der ganzen Welt genutzt wird, dann werden Sie wahrscheinlich einfach eine neue Funktion erstellen und die Dokumente für die alte Funktion aktualisieren wollen. Wenn Sie können, sollten Sie auch den Compiler aktualisieren, damit er ebenfalls Warnungen ausgibt. (Aber selbst dann kann es sein, dass Sie das bestehende System ändern können; erinnern Sie sich, als MS VC auf den C++-Standard umstellte und Sie alle Ihre Programme aktualisieren mussten. #include iostream s und fügen Sie using std s, um einfache, bestehende Konsolenanwendungen wieder zum Laufen zu bringen?)

Das hängt im Wesentlichen davon ab, welche Funktion man hat. Wenn es sich um etwas Grundlegendes handelt, das massive Auswirkungen hat, dann könnte es eine Menge Code zerstören. Wenn es sich nur um eine Nebenfunktion handelt, kann man sie genauso gut beheben. Wenn Sie Microsoft sind und Ihr anderer Code von einem Fehler in einer Ihrer Funktionen abhängt, sollten Sie ihn natürlich beheben, denn es ist einfach nur peinlich, ihn zu behalten. Wenn andere Entwickler sich auf den Fehler verlassen (der Sie haben ), dann haben Sie möglicherweise eine Verpflichtung gegenüber den Nutzern, deren Code, den Sie fehlerhaft gemacht haben, nicht zu zerstören.

Wenn Sie ein kleines Unternehmen oder ein unabhängiger Entwickler sind, dann können Sie die Funktion natürlich reparieren. Wenn Sie nur sich selbst oder ein paar Leute auf den neuesten Stand bringen müssen, dann ist es die beste Lösung, die Funktion zu reparieren, zumal es nicht einmal eine große Sache ist, denn alles, was es wirklich erfordert, ist ein zusätzlicher Hinweis in den Dokumenten für die Funktion. z.B. do not pass NULL o an exception is thrown if hWnd is the desktop etc.

Eine andere Möglichkeit als eine Art Kompromiss wäre es, eine Wrapper-Funktion zu erstellen. Sie könnten eine kleine Inline-Funktion erstellen, die die Args überprüft und dann die vorhandene Funktion aufruft. Auf diese Weise müssen Sie kurzfristig nicht viel tun, und wenn die Leute schließlich auf die neue Funktion umgestiegen sind, können Sie die alte Funktion verwerfen oder sogar entfernen und den Code zwischen den Überprüfungen einmal in die neue Funktion verschieben.

In den meisten Fällen ist es besser, eine fehlerhafte Funktion zu reparieren, insbesondere wenn Sie lediglich Argumentprüfungen hinzufügen, anstatt das Verhalten der Funktion vollständig zu ändern. Es ist nicht wirklich eine gute Idee, schlechten Code zu erleichtern - oder zu fördern - nur weil er einen bestehenden Code kaputt machen würde (besonders wenn der Code frei ist!) Denken Sie darüber nach: Wenn jemand ein neues Programm erstellt, kann er es von Anfang an tun, anstatt sich auf einen Fehler zu verlassen. Wenn sie ein altes Programm neu kompilieren, das von dem Fehler abhängt, können sie einfach den Code aktualisieren. Auch hier kommt es darauf an, wie unübersichtlich und verworren der Code ist, wie viele Leute davon betroffen sind und ob man dafür bezahlt wird oder nicht, aber es ist durchaus üblich, alten Code zu aktualisieren, um z.B. Variablen zu initialisieren, die noch nicht vorhanden sind, oder nach Fehlercodes zu suchen usw.

Zusammenfassend lässt sich sagen, dass Sie in Ihrem konkreten Beispiel (angesichts der zur Verfügung gestellten Informationen) das Problem einfach beheben sollten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X