Ich lese Coders at Work und darin wird viel über Invarianten geredet. Nach meinem Verständnis ist eine Invariante eine Bedingung, die sowohl vor als auch nach einem Ausdruck gilt. Sie sind unter anderem nützlich, um zu beweisen, dass die Schleife korrekt ist, wenn ich mich richtig an meinen Logikkurs erinnere.
Ist meine Beschreibung korrekt oder habe ich etwas verpasst? Haben Sie sie jemals in Ihrem Programm verwendet? Und wenn ja, wie haben sie davon profitiert?
invariants
gablin
quelle
quelle
Antworten:
In OOP ist eine Invariante eine Reihe von Aussagen, die während der Lebensdauer eines Objekts immer wahr sein müssen, damit das Programm gültig ist. Es sollte vom Ende des Konstruktors bis zum Start des Destruktors gültig sein, wenn das Objekt gerade keine Methode ausführt, die seinen Status ändert.
Ein Beispiel für eine Invariante könnte sein, dass genau eine der beiden Mitgliedsvariablen null sein sollte. Oder dass, wenn einer einen bestimmten Wert hat, die Menge der zulässigen Werte für den anderen dieser oder jener ist ...
Manchmal benutze ich eine Member-Funktion des Objekts, um zu überprüfen, ob die Invariante gültig ist. Ist dies nicht der Fall, wird eine Behauptung aufgestellt. Und die Methode wird am Anfang und Ende jeder Methode aufgerufen, die das Objekt ändert (in C ++ ist dies nur eine Zeile ...)
quelle
Nun, die Dinge, die ich in diesem Thread sehe, sind alle großartig, aber ich habe eine Definition einer "Invariante", die für mich bei der Arbeit enorm hilfreich war.
Diese Definition ist hilfreich, weil sie die Bedingungen in zwei Gruppen aufteilt: Denjenigen, denen der Compiler bei der Durchsetzung vertrauen kann, und denjenigen, die dokumentiert, diskutiert, kommentiert oder auf andere Weise an die Mitwirkenden kommuniziert werden müssen, damit sie mit der Codebasis interagieren können, ohne Fehler einzuführen .
Diese Definition ist auch hilfreich, da Sie die Verallgemeinerung "Invarianten sind schlecht" verwenden können.
Beispielsweise ist der Schalthebel in einem Schaltgetriebe so konstruiert, dass eine Invariante vermieden wird. Wenn ich wollte, könnte ich für jeden Gang ein Getriebe mit einem Hebel bauen. Dieser Hebel kann vorwärts ("eingerückt") oder rückwärts ("ausgerückt") sein. In einem solchen System habe ich eine "Invariante" erstellt, die als solche dokumentiert werden könnte:
Und so könnte man kaputte Sendungen für schlampiges Fahren verantwortlich machen. Moderne Autos verwenden jedoch einen einzelnen Steuerknüppel, der sich zwischen den Gängen dreht. Es ist so konstruiert, dass es bei einem modernen Schaltwagen nicht möglich ist, zwei Gänge gleichzeitig einzulegen.
Auf diese Weise können wir sagen, dass das Getriebe so konstruiert wurde, dass es die Invariante entfernt, da es sich nicht mechanisch so konfigurieren lässt, dass die logische Regel verletzt wird.
Jede Invariante dieser Art, die Sie aus Ihrem Code entfernen, stellt eine Verbesserung dar, da sie die kognitive Belastung der Arbeit damit verringert.
quelle
Eine Invariante (im gesunden Menschenverstand) bedeutet einige Bedingungen, die zu einem bestimmten Zeitpunkt oder sogar immer wahr sein müssen, während Ihr Programm ausgeführt wird. Zum Beispiel können PreConditions und PostConditions verwendet werden, um einige Bedingungen zu bestätigen, die wahr sein müssen, wenn eine Funktion aufgerufen wird und wenn sie zurückkehrt. Objektinvarianten können verwendet werden, um zu behaupten, dass ein Objekt während seiner Existenz einen gültigen Zustand haben muss. Dies ist das Design by Contract-Prinzip.
Ich habe informell Invarianten mit Checks in Code verwendet. Aber in jüngerer Zeit spiele ich mit der Codevertragsbibliothek für .NET , die Invarianten direkt unterstützt.
quelle
Basierend auf dem folgenden Zitat von Coders At Work ...
... Ich denke, "invariant" = "Bedingung, die Sie beibehalten möchten, um einen gewünschten Effekt zu erzielen".
Es scheint, dass die Invariante zwei Sinne hat, die sich auf subtile Weise unterscheiden:
Also ist 1 wie eine Behauptung; 2 ist wie ein Werkzeug zum Nachweis von Korrektheit, Leistung oder anderen Eigenschaften - denke ich. Im Wikipedia-Artikel finden Sie ein Beispiel für 2 (Beweis für die Richtigkeit der Lösung des MU-Puzzles).
Tatsächlich ist ein dritter Sinn der Invariante:
.3. Was soll das Programm (oder Modul oder Funktion) tun? Mit anderen Worten, sein Zweck.
Aus demselben Interview mit Coders At Work:
quelle
Eine Invariante ist wie eine Regel oder eine Annahme, die verwendet werden kann, um die Logik Ihres Programms zu diktieren.
Angenommen, Sie haben eine Softwareanwendung, die Benutzerkonten verwaltet. Angenommen, der Benutzer kann mehrere Konten haben, aber aus welchem Grund auch immer müssen Sie zwischen dem Hauptkonto eines Benutzers und den "Alias" -Konten unterscheiden.
Dies könnte ein DB-Datensatz oder etwas anderes sein, aber nehmen wir vorerst an, dass jedes Benutzerkonto durch ein Klassenobjekt dargestellt wird.
Klasse userAccount {private char * pUserName; private char * pParentAccountUserName;
...}
Eine Invariante könnte die Annahme sein, dass dieses Objekt das übergeordnete Konto ist, wenn pParentAccountUserName NULL oder leer ist. Mit dieser Invariante können Sie verschiedene Kontotypen unterscheiden. Es gibt wahrscheinlich bessere Methoden, um verschiedene Arten von Benutzerkonten zu unterscheiden. Denken Sie also daran, dass dies nur ein Beispiel ist, um zu zeigen, wie eine Invariante verwendet werden kann.
quelle
Aus der Physik kommend gibt es in der Physik Invarianten, also Größen, die nicht über die gesamte Berechnung / Simulation variieren. Beispielsweise wird in der Physik für ein geschlossenes System Gesamtenergie eingespart. Oder wieder in der Physik: Wenn zwei Teilchen kollidieren, müssen die resultierenden Fragmente genau die Energie enthalten, mit der sie begonnen haben, und genau den gleichen Impuls (eine Vektorgröße). Normalerweise gibt es nicht genügend Invarianten, um das Ergebnis vollständig zu spezifizieren. Zum Beispiel haben wir bei der 2-Teilchen-Kollision vier Invarianten, drei Impulskomponenten und eine Energiekomponente, aber das System hat sechs Freiheitsgrade (sechs Zahlen, um seinen Zustand zu beschreiben). Die Invarianten sollten auf einen Rundungsfehler konserviert werden, aber ihre Konservierung beweist nicht, dass die Lösung korrekt ist.
Daher sind diese Dinge in der Regel wichtig für die Überprüfung der geistigen Gesundheit, können jedoch selbst keine Korrektheit nachweisen.
quelle