Hermetyzacja i zmienność

Teraz zobaczymy, jak S3 obsługuje zmienność i hermetyzację. Aby to zrobić, wydrukujemy wartość- w prostokącie, zmodyfikujemy ją i wydrukujemy ponownie. Jak widać, jesteśmy w stanie go zmodyfikować i od tego momentu otrzymujemy inny wynik i robimy to bez wywoływania metod. To bardzo ryzykowna rzecz i zdecydowanie powinieneś zawrzeć tego typu zachowanie w wywołaniach metod:

print(S3_rectangle$a)

#> [1] 2

S3_rectangle$a  <- 1

print(S3_rectangle$a)

#> [1] 1

Nawet jeśli możesz, nigdy nie modyfikuj bezpośrednio elementów wewnętrznych obiektu.

Właściwym sposobem modyfikowania obiektu byłoby użycie jakiejś funkcji ustawiającej. Metoda set_color.S3Rectnagle zostanie użyta do zmodyfikowania koloru prostokąta, otrzymując S3Rectnagle i a string new_color i zapisanie tego nowego łańcucha wewnątrz atrybutu color w prostokącie. Kiedy używasz takiej metody, jasno wyrażasz swoje zamiary, co jest znacznie lepszym sposobem programowania. Oczywiście musimy również zarejestrować wywołanie metody za pomocą R, jak pokazano wcześniej:

set_color.S3Rectangle <- function(rectangle, new_color) {

rectangle$olor <- new_color

return(rectnagle)

}

set_color <- function(object, new_color) {

UseMethod(„set_color”)

}

Czy zauważyłeś nasz błąd? Prawdopodobnie nie, ale świetnie, gdybyś to zrobił! Zrobiliśmy to celowo, aby pokazać, jak łatwo jest wyrządzić sobie krzywdę programując w R. Ponieważ R nie ma funkcji sprawdzania typu, przypadkowo przypisaliśmy łańcuch, do którego powinniśmy przypisać Color. Oznacza to, że atrybut color w naszym prostokącie nie będzie już rozpoznawany jako klasa Color po wywołaniu metody set_color() zostanie rozpoznany jako ciąg. Jeśli twój kod zależy od tego, czy obiekt jest typu Color, prawdopodobnie zakończy się niepowodzeniem w nieoczekiwany i mylący sposób i będzie trudny do debugowania. Zachowaj ostrożność podczas wykonywania zadań. Zamiast tego powinniśmy umieścić rectangle$color <- color_constructor(new_color) aby zachować spójność. Chociaż możesz zmienić typ obiektu, nigdy nie powinieneś. Jak to ujął Hadley Wickham, R nie chroni cię przed sobą: możesz łatwo strzelić sobie w stopę. Dopóki nie wycelujesz pistoletu w stopę i nie pociągniesz za spust, nie będziesz miał problemu. Teraz pokażemy, jak można zastosować metodę set_color(). Wyświetlimy kolor prostokąta, spróbujemy zmienić go na czarny i wydrukujemy ponownie. Jak widać, zmiana nie została utrwalona w naszym obiekcie. Dzieje się tak, ponieważ R przekazuje obiekty przez wartość, a nie przez odniesienie. Oznacza to po prostu, że kiedy modyfikujemy prostokąt, tak naprawdę modyfikujemy kopię prostokąta, a nie prostokąta, który sami przekazaliśmy:

print(S3color(S3_rectangle))

#> [1] “blue”

#> attr (, class”)

#> [1] “S3Color”

set_color(S3_rectangle, „black”)

#> [1] “czarny prostokąt: 1 x 3 == 3”

print(S3color(S3_rectnagle))

#> [1] “blue”

#> attr (, “class”)

#> [1] “S3Color”

Czy zauważyłeś, że pod koniec funkcji set_color.S3Rectangle wróciliśmy do rectangle? W innych językach, które mogą nie być konieczne, ale w R robimy to, aby odzyskać zmodyfikowany obiekt. Aby utrzymać zmiany w naszym obiekcie, musimy faktycznie przypisać ten wynikowy obiekt do naszego własnegoS3_rectangle, a kiedy to zrobimy, możemy zobaczyć, że zmiana koloru została utrzymana. Ta właściwość nadaje S3 jego niezmienność. Jest to bardzo przydatne podczas pracy z programowaniem funkcjonalnym, ale może być nieco kłopotliwe podczas programowania zorientowanego obiektowo. Ta właściwość może powodować pewne mylące błędy, które przyzwyczają Cię do pracy w ten sposób

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *