Dobre praktyki programowania w Chmurze

Czy dobre praktyki programowania są potrzebne również w chmurach? Just Cloud

SOLID i inne dobre praktyki tworzenia oprogramowania są (mam nadzieję!) powszechnie znane i stosowane przez programistów na całym świecie. Pytamy o nie na rozmowach kwalifikacyjnych, wytykamy ich braki w przeglądzie kodu i mamy wyrzuty sumienia, gdy musimy przymknąć na nie oko, aby dostarczyć projekt na czas.

Jakub SikoraJakub Sikora. Instruktor Szkoły Chmury z wieloletnim doświadczeniem w roli Software Engineera. Od kilku lat znany jako współzałożyciel i CTO śląskiej fundacji Gruba.IT, a od niedawna również współtwórca startupu Fincastly.

Szkoła Chmury przygotowała dla Was zniżkę na kursy Software Development w chmurze Azure i AWS na -30%. Wystarczy, że wprowadzicie kod: JUSTCLOUD30 i zyskacie dostęp do wartościowej wiedzy!


W ostatnich latach świat rozwoju oprogramowania gruntownie się zmienił i obecnie, aby być dobrym i pożądanym na rynku programistą, trzeba dołożyć do swojego pudełka z narzędziami chmurę publiczną. Jak to zrobić, aby utrzymać wysoką jakość kodu także w chmurze? Jakie są dobre praktyki rozwoju aplikacji chmurowych i czy bardzo odbiegają od tych, które już znamy?

Błędne założenia przy tworzeniu systemów rozproszonych

Jako programiści często czynimy założenia. Czasem pomagają nam one dojść do celu i pokonać napotkany problem, lecz bywa, że stwarzają zagrożenie na środowisku produkcyjnym. Polecam ten artykuł o tzw. błędnych założeniach przy tworzeniu systemów rozproszonych (ang. fallacies of distributed systems).

Na przykład przy tworzeniu usługi do komunikacji z Service Busem czy wrappera dla punktu końcowego w Azure Functions powinniśmy zakładać nie tylko działające ścieżki, czy ewentualne błędy logiczne, ale również obsługę przypadków pogorszenia się stanu usługi, z którą się komunikujemy. Takie scenariusze najlepiej wyłapywać już na poziomie testów automatycznych (zarówno integracyjnych, jak i jednostkowych).

tips and tricks keyboard

Programowanie defensywne

Spora część zestawu praktyk zwanych Defensive Programming dotyczy zarówno zabezpieczania się przed niedostępnością usług trzecich czy problemami z asynchronicznością, jak i uwzględniania różnic w zachowaniu tych usług w zależności od środowiska. Aby skutecznie radzić sobie z podobnymi kwestiami, stworzono wiele wzorców, które możemy zaimplementować w kodzie:

Zastosowanie, chociażby jednej z tych praktyk znacząco zredukuje ryzyko konieczności spędzenia wielu długich godzin na gaszeniu pożaru na produkcji.

SOLID w chmurze

Już od dwóch dekad SOLID pomaga programistom tworzyć wysokiej jakości, łatwy w utrzymaniu kod. Ten prosty zestaw zasad powstał jednak w czasach, kiedy nikomu nie śniło się, że będziemy wdrażać aplikacje w jakiejś tam chmurze.

Jakiś czas temu Microsoft wydał ciekawy white paper na temat pierwszej zasady SOLID, Single Responsibility Principle (zasada pojedynczej odpowiedzialności). A co z kolejnymi? Spróbujmy przełożyć je na chmurę publiczną.

Open/Closed (otwarte-zamknięte)

Klasa, metoda, itd., powinny być otwarte na rozszerzenie swojej funkcjonalności, ale bez jednoczesnego bezpośredniego edytowania kodu źródłowego. Z doświadczenia wiem, że chociaż w teorii ta zasada brzmi prosto, to w codziennej pracy często o niej zapominamy. Jak przenieść to założenie do świata chmury?

Weźmy na przykład usługę Azure Function, która otrzymuje obraz, zmniejsza jego rozdzielczość, a następnie przesyła przetworzony plik do określonego folderu. Dodatkowo chcemy mieć również możliwość nakładania na pomniejszony obraz znaku wodnego. Zamiast rozszerzać tę konkretną funkcję o nowe linie kodu (i narażać się na wprowadzenie nowych błędów oraz złamanie pierwszej zasady SOLID), możemy stworzyć nową funkcję nasłuchującą na zmiany w folderze, do którego trafia pomniejszony obraz, i nakładającą znak wodny osobno na plik.

Liskov (zasada podstawienia Liskov)

Ta zasada mówi, że możliwość podstawienia obiektu o podtypie obiektu, który spodziewamy się otrzymać, nie powinna wymagać zmiany zachowania systemu. Zasadę podstawienia można zastosować nie tylko do interfejsu najmniejszych elementów w kodzie, takich jak klasy, ale również do interfejsów komunikacyjnych pomiędzy różnymi modułami systemu.

Komunikacja pomiędzy usługami w chmurze powinna być zaimplementowana w taki sposób, aby wymiana jednego z komponentów nie wiązała się z przepisywaniem wszystkich zależnych od niego modułów. Efekt taki można uzyskać, wykorzystując różne opcje komunikacji za pomocą eventów, wiadomości, czy poleceń, jak i stosując tradycyjną zasadę Liskov w kodzie – oddzielając się warstwą abstrakcji od konkretnej implementacji danej metody komunikacji.

Interface Segregation (segregacja interfejsów)

Żaden z bytów nie powinien zależeć od elementów interfejsu, których nie używa. Złamanie tej zasady ilustruje na przykład sytuacja, w której klasa ConsoleLogger implementuje interfejs IConsole z dwoma metodami ReadFromConsole i WriteToConsole. A to dlatego, że ConsoleLogger nie będzie używać metody czytającej dane wprowadzone przez użytkownika. Implementując ją, zanieczyszczamy logikę klasy, co może wpłynąć na jej późniejsze utrzymywanie.

Jak to przełożyć na chmurę? Np. kontener dockerowy z obrazem bazy danych nie potrzebuje wszystkich narzędzi zamkniętych w osobnym kontenerze, na którego obrazie budujemy komponenty systemu. Posegregowanie kontenerów i użycie ich do budowy nowych w zależności od faktycznych potrzeb pomoże uniknąć problemów z utrzymaniem takiego systemu.

Dependency Inversion (odwrócenie zależności)

Odwrócenie zależności to kwintesencja współczesnej chmury publicznej, w której większość tworzonej przez nas logiki może być zarządzana przez eventy dostarczane przez wiele usług typu EventGridIoT Hub, czy nawet przez zmiany w bazie danych. Zamiast tworzyć usługi, które bezpośrednio sterują logiką systemu od wewnątrz, można oprzeć kontrolę na reakcji na konkretne eventy i interakcje użytkowników z aplikacją (patrz Liskov).

Kluczowe wnioski

  • Pisząc kod aplikacji korzystającej z chmury publicznej, zakładaj, że wszystko, co może pójść nie tak, pójdzie nie tak. Zabezpiecz swój kod na taką ewentualność, korzystając z istniejących już wzorców.
  • SOLID ma zastosowanie nie tylko bezpośrednio w kodzie. Przełożenie praktyk na pracę z usługami w chmurze wpłynie pozytywnie na wydajność, łatwość utrzymywania i bezpieczeństwo Twojej aplikacji. Spróbuj znaleźć sposób na przełożenie jednej z zasad SOLID na Twój projekt i zaproponuj go swojemu zespołowi!

Zdjęcie główne artykułu pochodzi z unsplash.com.

Zapraszamy do dyskusji

Patronujemy

 
 
More Stories
mikrolokalizacja lokalizacja
Dźwięk jest lepszy od Bluetootha i WiFi. Dzięki niemu szybciej zlokalizujemy przedmioty