2015-01-04 8 views
5

Mit dem Schwerpunkt auf Unveränderlichkeit in Programmiersprache wie Scala (vermeiden Sie "var"), bedeutet es "state-modifying Methoden" in meinem Objekt muss eine Kopie der Instanz (mit der neue Staat)?Entwerfen mit Unveränderlichkeit (in Scala)

Betrachten wir Schildkröte. Ich möchte meine Schildkröte wie diese bewegen:

val turtle = new Turtle(0, 0, "north") 
val turtle2 = turtle.turnLeft().forward(5).turnRight().backward(2) 

Hier würde Turtle2 nicht auf der gleichen Instanz von Turtle zeigen (sie sind zwei getrennte Instanzen). Tatsächlich wurden in dieser Bewegungssequenz 4 vorläufige Objekte erzeugt. Dies ist, wie ich würde die Methode implementieren turnleft, zum Beispiel:

def turnLeft { 
    self.copy(orientation = self.orientation match { 
    case "north" => "west" 
    case "east" => "north" 
    case "south" => "east" 
    case "west" => "south" 
    }) 
} 

Ist die ein richtiger Design-Ansatz?

Wenn ja, wie effizient/ineffizient ist das (Erstellen eines neuen Objekts bei jedem Methodenaufruf)? Wenn nein, was wäre der richtige? Was ist falsch/fehlt in meinem Verständnis von Unveränderlichkeit Aspekt (oder vielleicht funktionale Programmierung im Allgemeinen)?

Vielen Dank im Voraus, Raka

+0

Ich denke, dass Ihr Code korrekt aussieht (aus einem unveränderlichen POV). In puncto Effizienz denke ich wird es sicherlich nicht so schnell wie ein einzelnes veränderbares vorbelegtes Objekt sein. Die Gesamtwirkung hängt davon ab, wie schnell und häufig Sie die Schildkröte bewegen möchten. –

+0

Danke, werde das beachten. –

Antwort

9

Schaffung von viel, viel kurzlebiger Objekte ist ein Markenzeichen Merkmal scala. Es ist im Allgemeinen nicht sehr teuer, vorausgesetzt, Sie führen es auf einer JVM mit einem ausreichend großen Heap aus und verfügen über eine ausreichende Menge an Speicher für junge Generationen, um die Abwanderung abzudecken.

Nachdem das gesagt wurde, ist Unveränderlichkeit keine Religion. Der gesunde Menschenverstand sollte vorherrschen und die Design-Entscheidungen leiten, bei denen das Festhalten am "Paradigma" zu anstrengend wird.

+0

Danke für die Antwort. Es macht mir nichts aus mit diesem Approach (kurzlebige Objekte zu erschaffen). ... Es ist nur ... manuell "Self.copy (...)" auf meinen "State-Modifying" -Methoden tun müssen, sieht umständlich. Gibt es einen besseren Weg, dies in Scala (spezielle Anmerkung für die Methode vielleicht) zu tun? –

+0

gut, 'copy (foo = bar)' scheint kaum zu viel mehr "cumesome" als 'foo = bar; gib das zurück, oder? Oder fehlt mir etwas? – Dima

1

Ich denke, es ist wichtig zu prüfen, ob Sie Ihre Turtle als eine Einheit behandeln möchten.

Wenn ich ein Auto habe und das Rad nach rechts fahre, fährt das Auto nach rechts (im optimalen Fall: P), dann drehe ich das Rad nach links, und es geht nach links, aber es ist immer noch das gleiche Auto. Das gleiche gilt für eine Schildkröte. Obwohl Unveränderlichkeit Programme normalerweise leichter verständlich macht, gibt es Fälle, in denen es weniger intuitiv ist.

Denken Sie darüber nach, ob eine rechte und eine linke Kopfschildkröte anders sind. Natürlich kann die Gleichheitsprüfung überschrieben werden, es ist also eher ein theoretischer Unterschied, ob die alte und die neue Turtle (mit dem gleichen Namen/der gleichen ID) nur durch Gleichheit oder auch nur durch den gleichen Wert identisch sind.