4 zasady tworzenia aplikacji w Scali

Scala, statycznie typowany, funkcyjny język programowania, jest na rynku już 20 lat (świętujemy urodziny Scali, sprawdź #scalaversary). W tym czasie wykształciło się kilka głównych podejść do pisania kodu w Scali. Obejmują one używanie systemów efektów, technik wykonania kodu asynchronicznego oraz korzystanie z różnych bibliotek i frameworków. Pisanie aplikacji w Scali to nie tylko wybór technologii, […] Artykuł 4 zasady tworzenia aplikacji w Scali pochodzi z serwisu Just Geek IT.

4 zasady tworzenia aplikacji w Scali

Scala, statycznie typowany, funkcyjny język programowania, jest na rynku już 20 lat (świętujemy urodziny Scali, sprawdź #scalaversary). W tym czasie wykształciło się kilka głównych podejść do pisania kodu w Scali. Obejmują one używanie systemów efektów, technik wykonania kodu asynchronicznego oraz korzystanie z różnych bibliotek i frameworków.

Pisanie aplikacji w Scali to nie tylko wybór technologii, ale również przestrzeganie uniwersalnych zasad, pomimo tego, że w samym języku mamy do czynienia z różnorodnymi podejściami. Niezależnie od używanego stosu technologicznego, pewne praktyki są zalecane, a innych należy unikać.

Te uniwersalne zasady wynikają z trzech filarów: samego języka, biblioteki standardowej oraz społeczności skupionej wokół Scali. Przyjrzymy się im bliżej, zwracając uwagę na różnice między Scalą a Javą. Takie podejście pozwoli Ci zrozumieć, co sprawia, że Scala jest wyjątkowa i jak można tworzyć lepsze aplikacje, korzystając z jej możliwości.

Niemutowalne struktury danych

Jedną z najbardziej fundamentalnych i istotnych cech kodu napisanego w Scali jest niemutowalność struktur danych. Istnieje wiele korzyści z takiego podejścia (oraz pewne wady):

  • dane nie mogą być modyfikowane „gdzieś indziej” przez „kogoś innego”
  • stan zewnętrzny względem funkcji nie może się zmienić, kod jest łatwiejszy do zrozumienia; nazywa się to także lokalnym wnioskowaniem
  • odporność na zniekształcenie danych, ponieważ nie jest możliwa równoległa modyfikacja danych
  • większe bezpieczeństwo wątków i ogólnie prostsze programowanie współbieżne

Inne platformy programistyczne również preferują niemutowalne struktury danych, jeśli chodzi o programowanie współbieżne. Scala robi to jednak standardowo, co może być powodem, dla którego jest tak dobrze przystosowana do programowania współbieżnego, które jest jedną ze scalowych nisz.

Scala wspiera niemutowalne struktury danych na wielu poziomach. Po pierwsze, mamy konstrukcje bezpośrednio w języku, takie jak case classes, pola klas, które domyślnie są stałymi (a nie zmiennymi), enums (w Scala 3) i ADTs (algebraiczne struktury danych). Innym ważnym aspektem jest łatwość tworzenia zmodyfikowanych struktur danych za pomocą automatycznie generowanych metod kopiujących.

Ale co równie ważne, biblioteka standardowa jest zbudowana wokół niemutowalnych struktur danych — jeśli potrzebujesz użyć Set, List, lub Map, domyślnie otrzymasz wersję niemutowalną.

Wreszcie, większość bibliotek Scali w swoim publicznym API konsumuje i produkuje niemutowalne struktury danych. To po prostu sposób na obsługę danych w Scali. Oczywiście, nadal możesz używać mutowalnych struktur danych, jeśli jest to potrzebne. Ale pamiętaj, że w świecie Scali jest to bardziej wyjątek od zasady, niż standardowa praktyka.

Nic nie stoi na przeszkodzie, by używać niemutowalnych struktur danych na innych platformach, w tym node.js, Java czy .NET. Jednak wsparcie językowe w tych przypadkach jest ograniczone. Co więcej, standardowe biblioteki i te często wykorzystywane przez społeczności programistów zazwyczaj opierają się na danych, które można zmieniać. Choć niemutowalność jest technicznie możliwa, w praktyce może okazać się dość niepraktyczna.

Na przykład, prawie wszystkie biblioteki Javy używają mutowalnych interfejsów kolekcji z biblioteki standardowej. Jeśli używasz biblioteki Javy, prawie na pewno będzie ona korzystać ze standardowych, mutowalnych kolekcji. To coś, co będzie prawie niemożliwe do zmiany: Java pozostanie językiem preferującym mutowalność.

Wyrażenia i wartości

Cechą Scali, która może nie wyróżnia się na pierwszy rzut oka, ale szybko staje się niezbędna, jest to, że wszystko w tym języku jest wyrażeniem. Gdy już się do tego przyzwyczaisz, pisanie w języku, w którym instrukcje i wyrażenia są oddzielone, będzie się wydawać uciążliwe i niepotrzebnie ograniczające.

Jest to dowód elastyczności Scali i wszechstronnej składni tego języka. W kontekście trzech filarów, które zdefiniowaliśmy na początku, orientacja na wyrażenia jest cechą czysto językową.

Pokrewną praktyką w Scali jest reprezentowanie różnych koncepcji jako wartości. Zaczynając od funkcji: składnia do definiowania wartości-funkcji jest bardzo lekka. W Scali po prostu czuje się to naturalnie. I jest to szeroko wykorzystywane zarówno przez bibliotekę standardową, która używa funkcji wyższego rzędu (czyli takich, które przyjmują inne funkcje jako parametry lub zwracają funkcje), jak również przez cały ekosystem, który korzysta z tego podejścia.

Ale nie kończy się to na funkcjach. Jedną z głównych zalet Scali jest jej elastyczność w definiowaniu abstrakcji. Często przekłada się to na możliwość reprezentowania różnych koncepcji jako wartości. Może to być nieco zaskakujące, ale dodanie takiego poziomu abstrakcji otwiera interesujące nowe możliwości.

Jako przykład weźmy funkcyjne systemy efektów, jak ZIO czy cats-effect. W nich całe obliczenie jest reprezentowane jako wartość. Dzięki temu otrzymujemy leniwe i kontrolowane wykonywanie kodu z efektami ubocznymi. To z kolei, w połączeniu z niestandardowym środowiskiem uruchomieniowym, umożliwia deklaratywną współbieżność, z wykorzystaniem lekkich wątków, solidnie zaprojektowanymi przerwaniami i łatwością refaktorowania.

Inny przykład z naszego własnego podwórka, to tapir i klient sttp. Oba mają do czynienia z domeną HTTP; w obu najpierw tworzysz wartość reprezentującą punkt końcowy lub żądanie HTTP. Ta wartość jest oczywiście niemutowalna, co pozwala na stopniowe udoskonalanie, jak również na oddzielenie warstw: sieciowej od domenowej.

    Oferty pracy z