2009-02-18 9 views
13

Jeśli dodaję nową klasę case, czy to znaczy, że muszę przeszukać cały kod dopasowania do wzorca i dowiedzieć się, gdzie należy obsłużyć nową klasę? Niedawno uczyłem się tego języka i kiedy czytałem o niektórych argumentach za i przeciw dopasowaniu wzorców, nie wiedziałem, gdzie powinien on być używany. Zobacz:Czy dopasowanie wzoru Scala narusza zasadę otwartą/zamkniętą?

Pro: Odersky1 i Odersky2

Con: Beust

Komentarze są dość dobre w każdym przypadku zbyt. A więc czy wzorzec pasuje do czegoś, z czego należy się ekscytować, czy czegoś, czego powinienem unikać? Właściwie wyobrażam sobie, że odpowiedź brzmi "zależy od tego, kiedy go użyjesz", ale jakie są pozytywne przypadki użycia i jakie są negatywne?

+0

Link Beust jest uszkodzony, widocznie do zmiany schematu URL. Próbowałem sprawdzić, czy mogę ustalić, który post jest przeznaczony, ale nie jestem pewien. Podaj poprawiony link lub dodatkowe informacje (jaki był tytuł wpisu?). –

Odpowiedz

22

Jeff, myślę, że masz właściwą intuicję: to zależy.

Hierarchie obiektów zorientowanych na obiekt z wirtualnym rozsyłaniem metod są dobre, gdy masz stosunkowo ustalony zestaw metod, które trzeba wdrożyć, ale wiele potencjalnych podklas, które mogą dziedziczyć z katalogu głównego hierarchii i implementować te metody. W takiej konfiguracji stosunkowo łatwo jest dodać nowe podklasy (wystarczy zaimplementować wszystkie metody), ale stosunkowo trudno jest dodać nowe metody (musisz zmodyfikować wszystkie podklasy, aby upewnić się, że poprawnie implementują nową metodę).

Typy danych z funkcjami opartymi na dopasowywaniu wzorców są dobre, gdy masz względnie ustalony zestaw klas, które należą do typu danych, ale wiele potencjalnych funkcji, które działają na tym typie danych. W takiej konfiguracji stosunkowo łatwo jest dodać nową funkcjonalność dla typu danych (tylko dopasowanie wzorca na wszystkich jego klasach), ale stosunkowo trudno jest dodać nowe klasy, które są częścią typu danych (musisz zmodyfikować wszystkie funkcje, które pasują do siebie na typie danych, aby upewnić się, że poprawnie obsługują nową klasę).

Kanonicznym przykładem podejścia OO jest programowanie GUI. Elementy GUI muszą obsługiwać bardzo mało funkcjonalności (rysowanie na ekranie to absolutne minimum), ale nowe elementy GUI są dodawane przez cały czas (przyciski, tabele, wykresy, suwaki itp.). Kanonicznym przykładem podejścia do dopasowywania wzorca jest kompilator. Języki programowania mają zazwyczaj względnie ustaloną składnię, więc elementy drzewa składni rzadko się zmieniają (jeśli w ogóle), ale stale dodawane są nowe operacje na drzewach składniowych (szybsze optymalizacje, dokładniejsza analiza typów itp.).

Na szczęście Scala pozwala łączyć oba podejścia. Klasy przypadków mogą być zarówno dopasowane do wzorca, jak i obsługiwać wysyłanie metodą wirtualną. Regularne klasy obsługują wysyłanie metod wirtualnych i mogą być dopasowywane do wzorca, definiując ekstraktor w odpowiednim obiekcie towarzyszącym. Do programisty należy decyzja, kiedy każde podejście jest odpowiednie, ale uważam, że oba są przydatne.

16

Podczas gdy szanuję Cedrica, on jest całkowicie w błędzie w tej kwestii. Dopasowywanie wzorców Scala może być w pełni obudowane ze zmian klas, gdy jest to pożądane. Chociaż prawdą jest, że zmiana klasy przypadku wymuszania zmiany odpowiadających instancji pasujących do wzorca, jest to możliwe tylko przy użyciu takich klas w sposób naiwny.

Scala dopasowuje wzór zawsze deleguje do dekonstruktora obiektu towarzyszącego klasy. W przypadku klasy case ten dekonstruktor jest generowany automatycznie (wraz z metodą fabrykową w obiekcie towarzyszącym), chociaż nadal można nadpisać tę automatycznie wygenerowaną wersję. Przez cały czas można uzyskać pełną kontrolę nad procesem dopasowywania wzorców, izolując wszelkie wzorce od potencjalnych zmian w samej klasie. Zatem porównywanie wzorców jest po prostu innym sposobem uzyskiwania dostępu do danych klas przez bezpieczny filtr enkapsulacji, tak jak każda inna metoda.

Tak więc opinia doktora Odersky'ego byłaby tym, któremu można zaufać, szczególnie biorąc pod uwagę ogromną liczbę badań, które przeprowadził w zakresie programowania obiektowego i projektowania.

Jeśli chodzi o miejsce, w którym powinno być używane, jest to całkowicie zgodne ze smakiem. Jeśli sprawi, że Twój kod będzie bardziej zwięzły i łatwy w utrzymaniu, używaj go! W przeciwnym razie nie rób tego. W przypadku większości programów obiektowych dopasowanie wzorca jest niepotrzebne. Jednakże, gdy zaczniesz integrować więcej funkcjonalnych idiomów (Option, List, itp.), Myślę, że przekonasz się, że dopasowanie wzorców znacznie zmniejszy obciążenie składniowe, jak również poprawi bezpieczeństwo oferowane przez system typów. Zasadniczo za każdym razem, gdy chcesz wyodrębnić dane, jednocześnie testując pewne warunki (np. Wyodrębniając wartość z Some), prawdopodobnie będzie można użyć dopasowania do wzorca.

1

Dopasowanie wzoru jest zdecydowanie dobre, jeśli wykonujesz programowanie funkcjonalne. W przypadku OO istnieją przypadki, w których jest dobrze. W samym przykładzie Cedrica zależy to od sposobu, w jaki konceptualnie postrzegasz metodę print(). Czy to zachowanie każdego obiektu Term? Czy jest to coś poza nim? Powiedziałbym, że jest na zewnątrz i ma sens, aby dopasować wzór. Z drugiej strony, jeśli masz klasę Employee z różnymi podklasami, jest to kiepski wybór, jeśli chodzi o dopasowywanie do wzorca jego atrybutu (np. Nazwa) w klasie bazowej.

Również dopasowywanie wzorów zapewnia elegancki sposób rozpakowywania członków klasy.

Powiązane problemy