2015-01-04 18 views
5

Z naciskiem na niezmienność w języku programowania jak Scala (unikanie "var"), oznacza to "metody modyfikujące stan" w moim obiekcie będą musiały zwrócić kopię instancji (z nowy stan)?Projektowanie z niezmiennością (w Scali)

Weźmy pod uwagę żółwia. Chciałbym przenieść żółwia tak:

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

Tutaj turtle2 nie wskazują na tej samej instancji Turtle (są dwie oddzielne instancje). W rzeczywistości w tej sekwencji ruchów powstały 4 obiekty pośrednie. W ten sposób zaimplementowałem metodę turnLeft, na przykład:

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

Czy to właściwe podejście do projektowania?

Jeśli tak, jak wydajne/nieefektywne jest to (tworzenie nowego obiektu przy każdym wywołaniu metody)? Jeśli nie, jaka byłaby właściwa? Co jest złego/brakuje mi w moim rozumieniu aspektu niezmienności (a może ogólnie programowania funkcjonalnego)?

Dzięki z góry, Raka

+0

Myślę, że Twój kod wygląda poprawnie (z niezmiennego POV). Jeśli chodzi o efektywność, to myślę, że na pewno nie będzie tak szybki, jak pojedynczy zmienny wstępnie przydzielony obiekt. Ogólny wpływ będzie zależeć od tego, jak szybko i często chcesz przenieść żółwia. –

+0

Dzięki, zauważę to. –

Odpowiedz

9

Stworzenie wiele, wiele przedmiotów nietrwałych jest cechą charakterystyczną cechą Scala. Generalnie nie jest to zbyt kosztowne, pod warunkiem, że uruchomisz go na JVM z odpowiednią wielkością stertą, mając wystarczającą ilość pamięci dla młodego pokolenia, aby pomieścić cały czas odejścia.

Powiedziawszy to, niezmienność nie jest religią. Zdrowy rozsądek powinien przeważać i kierować decyzjami projektowymi, w których trzymanie się "paradygmatu" staje się zbyt podatne.

+0

Dzięki za odpowiedź. Nie przeszkadza mi to z tym podejściem (tworzenia krótkotrwałych obiektów). ... Po prostu ... ręczne wykonanie "self.copy (...)" w moich metodach "modyfikujących stan" wygląda na kłopotliwe. Czy jest lepszy sposób na zrobienie tego w scala (może być specjalna adnotacja do metody)? –

+0

cóż, 'copy (foo = bar)' raczej wydaje się zbyt dużo bardziej "cumersome" niż 'foo = bar; zwróć to ", prawda? Czy może czegoś brakuje? – Dima

1

Myślę, że ważne jest, aby rozważyć, czy chcesz obsłużyć swój Turtle jako podmiot.

Jeśli mam samochód i obracam kierownicę w prawo, samochód jedzie w prawo (w optymalnym przypadku: P), a następnie skrętuję w lewo i jedzie w lewo, ale wciąż jest to ten sam samochód. To samo dotyczy żółwia. Mimo że niezmienność zazwyczaj ułatwia zrozumienie programów, zdarzają się sytuacje, gdy jest to mniej intuicyjne.

Zastanów się, czy prawy nagłówek i żółw po lewej stronie są różne. Oczywiście, sprawdzanie równości może być przesłonięte, więc jest to raczej teoretyczna różnica, czy stary i nowy żółw (o tej samej nazwie/identyfikatorze) są takie same tylko pod względem równości, czy też w sposób referencyjny.