2016-05-18 12 views
0

Es scheint, dass ich eine Frage nach der anderen stoße, wenn es sich bezieht, um die Baumstrukturbibliothek zu implementieren, aber das ist eine entscheidende.Wie man mit der Abwägung in der Baumstruktur zwischen Veränderlichkeit gegen Leistung umgehen kann

Angenommen, ich habe zwei Kernkonstruktoren: Tree und Node.
Während das Tree-Objekt über Methoden zum Verwalten der Struktur verfügt und Verweise auf Node-Objekte abrufen.

Das Problem, das ich nicht umgehen kann, ist, dass es scheint, dass die Node-Objekte (und ihre Kinder) unveränderlich sein müssen. Was wir nicht wollen, ist, dass der Benutzer der Bibliothek kann die innere Struktur mutieren:

var childNodes = Tree.findNode(5).children; 
var node = children[0]; 
node = "overwrite with something"; 

oder

var parentNode = Tree.findNode(5).parent; 
parentNode.children = { text: "Doesn't realize this will change the original node's children" }; 

Es wird den aktuellen Baum beeinflussen und schraubt das Innenleben auf.

Alternativ, wenn ich annehmen würde, mit unveränderlichen Objekten/Arrays zu arbeiten, impliziert es kontinuierliche Kopien.
Angenommen, ich möchte 10 zufällige Knoten über eine Baumstruktur zu (unter) einem einzigen Knoten verschieben. Das bedeutet, Kopien erstellen und ganze Arrays neu zuordnen, um sie zu mutieren. (Wir wissen nicht, wie lange die Arrays sein werden!). Dies scheint ein enormer Overkill für das zu sein, was bei veränderlichen Datenstrukturen nicht gekostet hat. Es fühlt sich in meiner Wirbelsäule an, dass es auch Code-mäßig umständlicher sein wird.

Ich habe viele Problemumgehungen versucht, aber am Ende mit dem gleichen Dilemma enden.
Wie löse ich das?

Edit: fast vergessen zu erwähnen, dass ich Arrays als Knoten Kinder verwenden, weil Reihenfolge für meinen Anwendungsfall wichtig ist.

+0

Haben Sie versucht, Objekt-Getter/Setter zu verwenden, um eine Form der Unveränderlichkeit zu erstellen? So habe ich es mit [relational-json] geschafft (https://github.com/SebastienDaniel/relational-json). Sehen Sie sich die Tabellenmethoden an, sie decken auch Arrays ab. Und die Perf. ist ganz in Ordnung. Nirgendwo in der Nähe von veränderbaren Objekten, aber immer noch ausreichend für den Produktionseinsatz. –

+0

@SebastienDaniel Die Sache ist, dass ich nicht sehe, wie es das Problem ändert. In dem Sinne ist das (denke ich), es wird immer noch eine Referenz zurückgeben, wenn es sich um Objekte handelt, und macht es nicht unveränderlich. Ich habe gelesen, dass Getter/Setter sehr teuer sind, was ich nicht sicher bin, ist eine gute Sache mit vielen Knoten ... – Trace

+0

Sie waren sehr teuer, als sie zum ersten Mal herauskamen, die Compiler haben viel bekommen besser. Zugegeben, wenn Sie Objekte zurückgeben, und nicht nur Primitive, dann sollten Sie in [ImmutableJS] (https://facebook.github.io/immutable-js/) suchen –

Antwort

0

Ich entschied mich für unveränderliche Knotenobjekte; Damit wird verhindert, dass der lib-Benutzer die internen Vorgänge versehentlich vermasselt.

Meine Sorge war über die Leistung, die wegen zu vieler Kopien leiden würde. Wie ich gelernt habe, gibt es einen performanten Weg, um mit unveränderlichen Objekten umzugehen, was Immutablejs aus der Box bietet.
Nachdem ich mir ein paar Präsentationen angesehen und die Dokumentation gelesen hatte, war ich angenehm überrascht von ihrer umfangreichen API, die die erforderliche Flexibilität bietet.

Strategie ist es, dem Benutzer die Wahl zwischen der Rückgabe entweder unveränderlicher Objekte oder nativer Javascript-Objekte zu bieten (bei der Arbeit mit React scheint Immutable eine sehr beliebte Wahl zu sein). Aber intern wird die Bibliothek unveränderliche Objekte verwenden.

@SebstienDaniel Danke für den Vorschlag, es war genau richtig.