Frage

ich ein paar Artikel auf Unveränderlichkeit gelesen habe, aber immer noch das Konzept folgt nicht sehr gut.

habe ich hier vor kurzem einen Thread, der Unveränderlichkeit erwähnt, aber da dies ein Thema an sich ist, mache ich einen eigenen Thread jetzt.

erwähnte ich in der Vergangenheit Thread, ich dachte, Unveränderlichkeit der Prozess ist ein Objekt macht nur lesen und geringe Sichtbarkeit zu geben. Ein anderes Mitglied sagte, dass es nicht wirklich etwas damit zu tun hat. Diese Seite (Teil eines

War es hilfreich?

Lösung

Was ist Unveränderlichkeit?

  • Unveränderlichkeit ist in erster Linie auf Objekte angewendet (Strings, Arrays, eine benutzerdefinierte Klasse Tier)
  • Normalerweise, wenn es eine unveränderliche Version einer Klasse ist, eine veränderbare Version ist ebenfalls verfügbar. Zum Beispiel, Objective-C und Cocoa definieren sowohl eine NSString-Klasse (unveränderlich) und eine NSMutableString Klasse.
  • Wenn ein Objekt unveränderlich ist, kann sie nicht mehr geändert werden, nachdem es erstellt wird (im Grunde nur lesen). Sie könnten als daran denken „nur der Konstruktor kann das Objekt ändern“.

Dies ist nicht direkt etwas mit Benutzereingaben zu tun hat; nicht einmal der Code den Wert eines unveränderlichen Objekt ändern. Sie können jedoch jederzeit ein neues unveränderliches Objekt erstellen, um es zu ersetzen. Hier ist ein Pseudo-Code Beispiel; beachten Sie, dass in vielen Sprachen Sie können einfach nicht myString = "hello"; stattdessen einen Konstruktor verwenden, wie ich unten tat, aber ich eingeschlossen es für Klarheit:

String myString = new ImmutableString("hello");
myString.appendString(" world"); // Can't do this
myString.setValue("hello world"); // Can't do this
myString = new ImmutableString("hello world"); // OK

Sie erwähnen „ein Objekt, das nur Informationen gibt“; dies macht es nicht automatisch ein guter Kandidat für Unveränderlichkeit machen. Unveränderliche Objekte sind in der Regel den gleichen Wert immer zurück, die sie mit aufgebaut wurden, so dass ich bin geneigt, die aktuelle Zeit nicht zu sagen, wäre ideal, da diese oft ändert. Allerdings könnten Sie eine MomentOfTime Klasse, die mit einem bestimmten Zeitstempel erstellt wird und immer wieder, dass ein Zeitstempel in der Zukunft.

Vorteile von Immutabilty

  • Wenn Sie ein Objekt an einem anderen Funktion / Methode übergeben, sollten Sie sich nicht darum kümmern, ob das Objekt den gleichen Wert, nachdem die Funktion zurückkehrt haben. Zum Beispiel:

    String myString = "HeLLo WoRLd";
    String lowercasedString = lowercase(myString);
    print myString + " was converted to " + lowercasedString;
    

    Was passiert, wenn die Umsetzung der lowercase() myString geändert, wie es war eine Kleinversion zu erstellen? Die dritte Zeile würde Ihnen nicht das gewünschte Ergebnis wollten. Natürlich wäre eine gute lowercase() Funktion dies nicht tun, aber Sie diese Tatsache garantiert, wenn myString unveränderlich ist. Als solche unveränderlichen Objekte gute objektorientierte Programmierung Praktiken erzwingen helfen können.

  • Es ist einfacher, ein unveränderliches Objekt thread-safe

  • machen
  • Sie vereinfacht möglicherweise die Implementierung der Klasse (schön, wenn du derjenige Schreiben der Klasse sind)

Staat

Wenn Sie alle ein Objekts Instanzvariablen nehmen sind und schreiben ihre Werte auf dem Papier, das wäre der Zustand des Objekts zu diesem Zeitpunkt. Der Zustand des Programms ist der Zustand aller Objekte zu einem bestimmten Zeitpunkt. Zustandsänderungen schnell im Laufe der Zeit; ein Programm benötigt Zustand zu ändern, um weiter ausgeführt.

Unveränderliche Objekte haben jedoch Zustand im Laufe der Zeit festgelegt. Einmal erstellt, wird der Zustand eines unveränderliches Objekt nicht als Ganzes könnte, obwohl der Zustand des Programms ändern. Dies macht es einfacher, den Überblick zu behalten, was geschieht (und andere Vorteile siehe oben).

Andere Tipps

Unveränderlichkeit

Einfach ausgedrückt, Speicher ist unveränderlich, wenn es nicht nach dem bei der Initialisierung geändert wird.

Programme in imperativen Sprachen geschrieben wie C, Java und C # können im Speicher befindlichen Daten nach Belieben manipulieren. Ein Bereich des physikalischen Speichers, einmal beiseite gestellt, während der Ausführung des Programms jederzeit von einem Ausführungs-Thread in ganz oder teilweise geändert werden. In der Tat fördern imperative Sprachen diese Art der Programmierung.

Schreiben Programme auf diese Weise wurden für Single-Threaded-Anwendungen unglaublich erfolgreich. Da jedoch moderne Anwendungsentwicklung bewegt sich auf mehrere gleichzeitige Threads des Betriebs in einem einzigen Prozess, eine Welt der möglichen Probleme und die Komplexität eingeführt wird.

Wenn nur ein Thread der Ausführung ist, kann man sich vorstellen, dass diese einzelnen Thread alle Daten im Speicher ‚besitzt‘, und so damit es nach Belieben manipulieren kann. Allerdings gibt es keine implizite Konzept des Eigentums, wenn mehrere Threads der Ausführung beteiligt sind.

Stattdessen fällt diese Last auf den Programmierer, der zu großen Schmerzen gehen müssen, um sicherzustellen, dass In-Memory-Strukturen in einem konsistenten Zustand für alle Leser sind. Verriegelungs Konstrukte müssen vorsichtig in Maßnahme verwendet werden einen Faden zu verbieten, Daten zu sehen, während er von einem anderen Thread aktualisiert wird. Ohne diese Koordination würde ein Faden verbraucht zwangsläufig Daten, die nur zur Hälfte wird aktualisiert. Das Ergebnis aus einer solchen Situation ist unberechenbar und oft katastrophal. Außerdem Code macht Verriegelungs Arbeit richtig ist notorisch schwierig und wenn schlecht gemacht kann die Leistung oder, im schlimmsten Fall lähmt, Fall Deadlocks, die Ausführung anhält unwiederbringlich.

unveränderliche Datenstrukturen verringert die Notwendigkeit, komplexe Schließanlagen in Code einzuführen. Wenn ein Abschnitt des Speichers ist nicht garantiert, während der Laufzeit eines Programms zu ändern, dann können mehrere Leser gleichzeitig auf den Speicher zugreifen. Es ist nicht möglich, dass sie, dass bestimmte Daten in einem inkonsistenten Zustand zu beobachten.

Viele funktionalen Programmiersprachen wie Lisp, Haskell, Erlang, F # und Clojure, unveränderliche Datenstrukturen durch ihre Natur fördern. Es ist aus diesem Grund, dass sie ein Wiederaufleben des Interesses erfreuen, wie wir zu einer zunehmend komplexen Multi-Threaded-Anwendungsentwicklung und viel Computer Computerarchitekturen zu bewegen.

Staat

Der Zustand einer Anwendung kann einfach als die Inhalte aller Speicher- und CPU-Registers zu einem bestimmten Zeitpunkt betrachtet werden.

Logischerweise kann ein Programm des Landes in zwei Teile geteilt werden:

  1. Der Zustand des Haufens
  2. Der Zustand des Stapels von jedem ausgeführten Thread

In verwalteten Umgebungen wie C # und Java, kann ein Thread Zugriff auf den Speicher nicht von anderen. Deshalb ‚besitzt‘ jeder Thread den Zustand seines Stapels. Der Stapel kann gedacht werden als Halt lokale Variablen und Parameter des Werttypen (struct) und die Verweise auf Objekte. Diese Werte werden isoliert von Außengewinden.

Allerdings sind die Daten auf dem Heap unter allen Threads gemeinsam nutzbar ist, also darauf zu achten, den gleichzeitigen Zugriff zu steuern, getroffen werden. Alle Referenztyp (class) Objektinstanzen werden auf dem Heap gespeichert.

In OOP, der Zustand einer Instanz einer Klasse wird durch seine Felder bestimmt. Diese Felder werden auf dem Heap gespeichert und sind so zugänglich von allen Threads. Wenn eine Klasse definiert, die Methoden Felder ermöglichen modifiziert werden, nachdem der Konstruktor abgeschlossen ist, dann ist die Klasse wandelbar (nicht unveränderlich). Wenn die Felder nicht in irgendeiner Weise verändert werden, dann ist der Typ unveränderlich. Es ist wichtig zu beachten, dass eine Klasse mit allen C # readonly / Java final Feldern nicht notwendigerweise unveränderlich ist. Diese Konstrukte sorgen für das Hinweis nicht ändern kann, aber nicht das referenzierte Objekt. Zum Beispiel kann ein Feld einen unveränderbaren Verweis auf eine Liste von Objekten, aber die eigentlich Content der Liste kann jederzeit geändert werden.

einen Typs als wirklich unveränderlich Durch die Definition, sein Zustand eingefroren betrachtet werden kann und daher die Art ist sicher für den Zugriff durch mehrere Threads.

In der Praxis kann es unbequem sein, um alle Ihre Arten als unveränderlich zu definieren. So ändern Sie können den Wert auf einer unveränderlichen Art ein gutes Stück von Speicherkopieren einzubeziehen. Einige Sprachen machen diesen Prozess einfacher als andere, aber so oder so wird die CPU dabei einige zusätzliche Arbeit beenden. Viele Faktoren tragen zu bestimmen, ob der Zeitspeicher überwiegt die Auswirkungen der Sperrung Behauptungen aufgewendet zu kopieren.

Eine Menge Forschung in die Entwicklung von unveränderlichen Datenstrukturen wie Listen und Bäume verschwunden. Wenn solche Strukturen unter Verwendung von, sagen wir eine Liste, die ‚add‘ Betrieb einen Verweis auf eine neue Liste zurück mit dem neuen Element hinzugefügt. Bezugnahmen auf die vorherige Liste keine Veränderung sehen und immer noch eine konsistente Sicht auf die Daten haben.

Um es einfach zu sagen: Sobald Sie ein unveränderliches Objekt zu erstellen, gibt es keine Möglichkeit, den Inhalt dieses Objekt zu ändern. Beispiele für .Net unveränderliche Objekte sind String und Uri.

Wenn Sie eine Zeichenfolge ändern, geben Sie einfach einen neuen String bekommen. Die ursprüngliche Zeichenfolge wird sich nicht ändern. Ein Uri hat nur Nur-Lese-Eigenschaften und keine Methoden zur Verfügung, den Inhalt des Uri zu ändern.

Fälle, die unveränderliche Objekte sind wichtig, sind vielfältig und in den meisten Fällen haben mit Sicherheit zu tun. Die Uri ist ein gutes Beispiel. (Zum Beispiel Sie wollen nicht ein Uri durch einen nicht vertrauenswürdigen Code geändert werden.) Das bedeutet, dass Sie einen Verweis auf ein unveränderliches Objekt passieren können um ohne den Inhalt ändern jemals zu kümmern.

Hoffe, das hilft.

Dinge, die unveränderlich sind nie ändern. Mutable Dinge können sich ändern. Mutable Dinge mutieren. Unveränderliche Dinge erscheinen ein neues wandelbar, was aber tatsächlich schaffen zu ändern.

Zum Beispiel ist hier eine Karte in Clojure

(def imap {1 "1" 2 "2"})
(conj imap [3 "3"])
(println imap)

Die erste Zeile erstellt eine neue unveränderliche Clojure Karte. Die zweite Zeile dockt 3 und „3“ auf der Karte. Dies scheint, als ob es die alte Karte zu modifizieren, aber in Wirklichkeit ist es eine neue Karte mit 3 „3“ hinzugefügt zurück. Dies ist ein hervorragendes Beispiel für Unveränderlichkeit. Wenn dies eine veränderbare Karte gewesen wäre es einfach hinzugefügt 3 „3“ direkt die gleiche alte Karte. Die dritte Zeile druckt die Karte

{3 "3", 1 "1", 2 "2"}

Unveränderlichkeit hilft, Code sauber und sicher. Diese und andere Gründe, warum funktionalen Programmiersprachen tendieren zu Unveränderlichkeit und weniger Statusbehaftung zu lehnen.

Gute Frage.

Multi-Threading. Wenn alle Arten unveränderlich sind dann Bedingungen Rennen nicht vorhanden sind, und Sie sind sicher, wie viele Threads auf den Code zu werfen, wie Sie wollen.

Natürlich kann man nicht so viel erreichen, ohne Veränderlichkeit speichern komplexe Berechnungen, so dass Sie in der Regel eine gewisse Veränderlichkeit benötigen funktionale Business-Software zu erstellen. Allerdings lohnt es sich, zu erkennen, wo Unveränderlichkeit wie etwas Transaktions liegen sollte.

Sehen Sie funktionale Programmierung und das Konzept der Reinheit für weitere Informationen über die Philosophie. Je mehr Sie speichern auf den Call-Stack (die params sind Sie auf Methoden vorbei) im Gegensatz zu was sie über Referenzen zur Verfügung, wie Sammlungen oder statisch verfügbaren Objekte der reineren Ihr Programm ist und die weniger anfällig für Race Conditions Sie sein. Mit Multi-Cores in diesen Tagen ist dieses Thema immer wichtiger.

Auch Unveränderlichkeit reduziert die Menge an Möglichkeiten im Programm, die für Bugs mögliche Komplexität und Potenzial reduziert.

Ein unveränderliches Objekt ist etwas, was man mit Sicherheit davon ausgehen kann, nicht ändern wird; es hat die wichtige Eigenschaft, dass jeder mit ihm annehmen, können sie den gleichen Wert sind zu sehen.

Unveränderlichkeit bedeutet in der Regel auch Sie einen „Wert“ des Objekts als denken kann, und dass es keine effektive Unterschied zwischen identischen Kopien des Objekts und das Objekt selbst.

Die Dinge unveränderlich verhindert, dass eine große Anzahl von häufigen Fehlern.

Zum Beispiel sollte ein Schüler nie ihre Schüler # Änderung auf sie hat. Wenn Sie die Variable nicht bieten eine Möglichkeit, setzen (und es const zu machen, oder endgültig, oder was auch immer Ihre Sprache unterstützt), dann können Sie, dass bei der Kompilierung erzwingen.

Wenn die Dinge sind wandelbar und Sie wollen nicht, sie zu ändern, wenn Sie sie laufen um Ihnen eine defencive Kopie machen müssen, die Sie weitergeben. Dann, wenn die Methode / Funktion können Sie die Kopie des Elements aufrufen ändert, ist das Original unberührt.

Die Dinge unveränderlich heißt, Sie müssen sich nicht daran erinnern (oder die Zeit / Speicher nehmen) defencive Kopien zu machen.

Wenn Sie wirklich daran arbeiten, und darüber nachdenken, jede Variable, die Sie machen, werden Sie feststellen, dass die überwiegende Mehrheit (I haben in der Regel 90-95%) Ihrer Variablen ändern sich nie, wenn sie einen Wert angegeben. Dadurch wird die Anzahl der Fehler zu folgen und reduziert Programme erleichtert.

Ihre Frage auf Zustand zu beantworten, ist Zustand die Werte, die Variablen eines „Objekt“ (sein, dass eine Klasse oder eine Struktur) hat. Wenn Sie eine Person „Objekt“ nehmen Zustand wäre Dinge wie Augenfarbe, Haarfarbe, Haarlänge, etc ... einige von denen (sagen Augenfarbe) nicht ändern, während andere, wie Haarlängenänderung zu tun.

"... warum soll mich darum kümmern?"

Ein praktisches Beispiel ist wiederholende Verkettung von Strings. In .NET zum Beispiel:

string SlowStringAppend(string [] files)
{
    // Declare an string
    string result="";

    for (int i=0;i<files.length;i++)
    {
        // result is a completely new string equal to itself plus the content of the new
        // file
        result = result + File.ReadAllText(files[i]);
    }

    return result;
}    

string EfficientStringAppend(string [] files)
{
    // Stringbuilder manages a internal data buffer that will only be expanded when absolutely necessary
    StringBuilder result=new SringBuilder();

    for (int i=0;i<files.length;i++)
    {
        // The pre-allocated buffer (result) is appended to with the new string 
        // and only expands when necessary.  It doubles in size each expansion
        // so need for allocations become less common as it grows in size. 
        result.Append(File.ReadAllText(files[i]));
    }

    return result.ToString();
}

Leider ist der erste (langsam) Funktion Ansatz ist immer noch häufig verwendet. Ein Verständnis der Unveränderlichkeit macht es sehr klar, warum String mit so wichtig ist.

Sie können ein unveränderliches Objekt ändern, deshalb müssen Sie es ersetzen .... „sie zu ändern“. d.h. ersetzen dann verwerfen. „Ersetzen“ in diesem Sinne bedeutet, den Zeiger von einem Speicherplatz zu ändern (von dem alten Wert) zu einem anderen (für den neuen Wert).

Beachten Sie, dass dies jetzt in machen wir zusätzliche Speicher verwenden. Einige für den alten Wert, einige für den neuen Wert. Beachten Sie auch, einige Leute sind verwirrt, weil sie an Code aussehen, wie zum Beispiel:

string mystring = "inital value";
mystring = "new value";
System.Console.WriteLine(mystring); // Outputs "new value";

und denken sich: „aber ich bin es zu ändern, suchen Sie genau dort, in schwarz und weiß! MyString Ausgänge‚neuen Wert‘...... Ich dachte, Sie sagten ich es nicht ändern kann? !!“

Aber eigentlich unter der Haube, was geschieht diese Zuordnung neuer Speicher heißt mystring nun an einer anderen Speicheradresse und Raum zeigt. „Unveränderliche“ in diesem Sinne bezieht sich nicht auf den Wert von mystring sondern der Speicher durch die Variable mystring verwendet seinen Wert zu speichern.

In bestimmten Sprachen der Speicher den alten Wert zu speichern manuell gereinigt werden muss das heißt der Programmierer muss es explizit freigeben ..... und denken Sie daran, dies zu tun. In anderen Sprachen ist dies eine automatische Funktion der Sprache heißt Garbage Collection in .NET.

Einer der Orte, an denen wirklich bläst re: Speichernutzung ist in sehr iterativen Schleifen, speziell mit Strings als in Ashs' Post. Sagen Sie bitte eine HTML-Seite in einer iterativen Schleife bauen, wo man ständig den nächsten HTML-Block zum letzten und nur für Kicks angefügt, taten Sie dies auf einem hohen Volumen-Server. Diese konstante Zuordnung der „neuen Wertspeicher“ kann schnell teuer werden, und letztlich fatal, wenn der „alte Wertspeicher“ ist, setzt sich nicht richtig gereinigt.

Ein weiteres Problem ist, dass einige Leute nehmen Dinge wie Garbage Collection (GC) geschieht sofort. Aber es funktioniert nicht. Es gibt verschiedene Optimierungen, die so auftreten, dass die Garbage Collection gesetzt wird während der mehr Ruheperioden auftreten. So kann es eine erhebliche Verzögerung zwischen dem, wenn der Speicher gekennzeichnet ist als verworfen, und wenn sie tatsächlich vom Garbage Collector freigegeben wird .... so können Sie große Speicherauslastungsspitzen leiden, wenn Sie einfach das Problem auf die GC verschieben.

Wenn der GC keine Chance bekommen zu arbeiten, bevor Sie über genügend Arbeitsspeicher ausgeführt, dann Dinge wont fallen notwendigerweise über wie auch in anderen Sprachen, die nicht automatische Garbage Collection verfügen. Stattdessen wird der GC als höchste Priorität Prozess treten, um den verworfenen Speicher freizugeben, egal wie schlecht das Timing, und einen Sperrprozess werden, während sie die Dinge bereinigt. Offensichtlich ist dies nicht cool.

Also im Grunde, müssen Sie sich mit diesen Dingen im Kopf codieren und für die Sprachen in die Dokumentation sehen Sie die besten Praktiken / Muster verwenden, die es Ihnen ermöglichen, dieses Risiko zu vermeiden / mindern.

Wie in Ashs' Post, in .Net und mit Streichern, die empfohlene Praxis ist die veränderbare String Klasse zu verwenden, anstatt die unveränderlichen String-Klassen, wenn es um die Notwendigkeit geht, ständig einen Strings Wert zu ändern.

Andere Sprachen / Typen werden in ähnlicher Weise ihre eigenen Abhilfen haben.

Sehen Sie, ich habe nicht die Links lesen, die Sie gebucht haben.

Doch hier ist mein Verständnis.
Jedes Programm hält einige Kenntnisse über seine Daten (State), die entweder durch Benutzereingabe / externe Veränderungen usw. ändern kann.

Variablen (Werte, die ändern) gehalten werden Zustand zu halten. Unveränderliche bedeutet einige Daten, die sich nicht verändert. Man kann sagen, es als Nur-Lese-oder konstant in irgendeiner Weise gleich ist (es es auf diese Weise zu sehen ist).

AFAIK, funktionale Programmierung hat Dinge unveränderlich (das heißt nicht Zuweisung zu einer Variablen halten den Wert verwenden können. Was können Sie tun, ist eine andere Variable erstellen, die den ursprünglichen Wert + Änderungen halten kann).

.net hat String-Klasse, die ein Beispiel.
das heißt Sie können nicht Zeichenfolge an seiner Stelle

ändern

string s = "Hallo"; Ich kann s.Replace ( "el", "a") schreiben; Aber das wird nicht den Inhalt der Variablen s ändern.

Was ich tun kann, ist, s = s.Replace ( "el", "a");
Dadurch wird eine neue Variable erstellen und zuweisen seinen Wert s (Inhalt s überschreiben).

Die Experten können Fehler korrigieren, wenn ich in meinem Verständnis.

EDIT: (vielleicht) Immutable = unassignable, sobald es einen gewissen Wert hält und nicht an Ort und Stelle ersetzt werden,

Ein Beispiel für die möglichen Leistungsvorteile durch unveränderliche Objekte angeboten wird, ist in dem WPF-API zur Verfügung. Eine gemeinsame Basisklasse von vielen WPF-Typen ist Freezable.

Mehrere WPF Beispiele legen nahe, dass Objekte Einfrieren (so dass sie zur Laufzeit unveränderlich) Anwendungsleistung verbessern kann deutlich als Sperre und Kopieren ist nicht erforderlich.

Persönlich mag ich das Konzept der Unveränderlichkeit leichter war, in der Sprache auszudrücken ich am häufigsten verwenden, C #. Es gibt einen readonly Modifikator für Felder. Ich möchte auch einen readonly Modifikator auf Arten sehen, die nur bei den Typen erlaubt würden, die nur Nur-Lese-Felder, die von Nur-Lese-Typen sind. Im Wesentlichen bedeutet dies, dass alle Zustand bei Bauzeit injiziert werden muß, und das und die gesamte Objektgraphen würde eingefroren werden. Ich stelle mir vor, dass diese Metadaten wesentlicher Bestandteil des CLR wurden dann könnte es leicht für GC zu optimieren Müllanalyse verwendet werden.

Sorry, warum nicht daran hindert Unveränderlichkeit Race Conditions (in diesem Beispiel schreiben, nachdem lesen Gefahren)?

shared v = Integer(3)
v = Integer(v.value() + 1) # in parallel

Unveränderlichkeit ist über Werte und Werte sind über Fakten. Es muss etwas Wert, wenn unveränderlich ist, denn wenn etwas geändert werden kann, dann bedeutet dies, dass kein spezifischer Wert kann mit ihm verbunden werden. Das Objekt wurde mit dem Zustand A und während der Programmausführung initialisiert wurde mutiert in dem Zustand B und Zustand C. Das bedeutet, dass das Objekt nicht einzelnen bestimmten Wert darstellt, sondern ist nur ein Container, Abstraktion auf einem Platz im Gedächtnis, nichts weiter. Sie können nicht das Vertrauen auf solche Behälter haben, kann man nicht glauben, dass dieser Behälter hat den Wert Sie annehmen sollte.

Lassen Sie uns zum Beispiel gehen - lässt sich vorstellen, dass in Code Instanz von Klasse Book erstellt wird.

Book bookPotter =  new Book();
bookPotter.setAuthor('J.K Rowling');
bookPotter.setTitle('Harry Potter');

Diese Instanz hat einige Felder gesetzt wie Autor und Titel. Alles ist in Ordnung, aber in einem gewissen Teil des Codes wieder Setter verwendet.

Book bookLor =  bookPotter; // only reference pass
bookLor.setAuthor('J.R.R Tolkien');
bookLor.setTitle('Lords of The Rings');

Sie nicht durch unterschiedliche Variablennamen betrogen werden, eigentlich ist es die gleiche Instanz. Der Code wird mit Setter auf derselben Instanz wieder. Es bedeutet, dass bookPotter war nie wirklich die Harry-Potter-Buch, bookPotter nur Zeiger auf den Ort, an dem unbekannten Buch befindet. Das heißt, es sieht aus wie es ein Regal ist dann das Buch. Was Vertrauen können Sie auf solches Objekt? Es ist Harry-Potter-Buch oder LoR Buch oder keines von beiden?

Mutable Instanz einer Klasse ist nur ein Zeiger auf einen unbekannten Zustand mit den Klassenmerkmalen.

Wie dann Mutation vermeiden? Es ist ganz einfach in Regeln:

  • konstruiert Objekt mit gewünschtem Zustand über Konstruktor oder Builder
  • schafft keine Setter für gekapselte Zustand des Objekts
  • ändert keinen gekapselten Zustand des Objekts in jedem seiner Methoden

Diese wenige Regeln erlauben berechenbare und zuverlässige Objekte zu haben. Zurück zu unserem Beispiel und buchen Sie folgende obige Regeln:

Book bookPotter =  new Book('J.K Rowling', 'Harry Potter');
Book bookLor = new Book('J.R.R Tolkien', 'Lord of The Rings');

Alles ist während der Konstruktion Phase, in diesem Fall Konstruktor festgelegt, aber für größere Strukturen kann es ein Baumeister sein. Keine Setter existieren in Objekte, Buch nicht anderes mutieren kann. In einem solchen Fall stellt bookPotter Wert von Harry-Potter-Buch, und Sie können sicher sein, dass diese unveränderliche Tatsache ist.

Wenn Sie in einem breiteren Anwendungsbereich Unveränderbarkeit interessiert sind, in diesem Medium Artikel ist mehr über das Thema in Bezug auf JavaScript - https://medium.com/@macsikora/the-state-of-immutability-169d2cd11310 .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top