O co chodzi w KISS?

Cześć. Ostatnie wpisy głównie skupiają się na pisaniu czystego kodu więc i dziś zarzucę kolejnym akronimem. KISS – to akronim od Keep It Simple Stupid. Pewnie zastanawiasz się, po co ja o tym piszę… Uważam, że jest to jedna z najważniejszych zasad pisania czytelnego kodu.

KISS nie jest zbiorem zasad jak SOLID, bardziej jest podobny do zasady DRY, czyli mówi nam, że musimy o czymś pamiętać, ale nie definiuje konkretnych reguł. KISS mówi nam o tym, aby zawsze pisząc kod mieć, z tyłu głowy, aby wszystko, co piszemy, było maksymalnie proste i czytelne.

Ważne, aby kod, który piszemy, nie był przekombinowany. Czasem probując wdrożyć powszechnie znane dobre praktyki w postaci wzorców projektowych, sprawiamy, że kod przestaje być czytelny. W takich przypadkach warto szukać złotego środka.

Opowiem Ci teraz przykład z życia wzięty, gdzie nie zastosowałem się do tej zasady. Pewnego razu dostałem zadanie rekrutacyjne. Zadanie polegało na napisaniu prostej aplikacji symulującej działanie maszyny vendingowej. Samo zadanie nie było trudne, ale niesamowicie ambitny Michał postanowił nadać klasom bardzo ładnie nazwy. Jednym z obiektów był sejf na monety wrzucane do maszyny. Nazwałem go zgodnie z tym co wyszukałem w google – Peter, a mogłem po prostu Safe.

Rezultat był taki, że feedback z zadania był negatywny a komentarz brzmiał “Przez pół godziny zastanawialiśmy się, co oznacza Peter w kontekście Twojej aplikacji”.

Podsumowanie

Wniosek z tego taki, że najprostsze rozwiązania są najlepsze i nie ma co za bardzo kombinować. Z programowaniem jest trochę jak z maturę z matematyki. Jeśli zadanie jest na 2 punkty, a Ty robisz już piątą linijkę obliczeń, to znaczy, że już przekombinowałeś (-aś).

Jeśli artykuł Ci się podobał, zapraszam do polubienia profilu na facebooku oraz obserwowania na instagramie. Zapraszam również do grupy Wsparcie w programowaniu i zadawania pytań oraz do kontaku.

Czy zasada DRY powinna być zawsze stosowana?

W tym całym IT strasznie dużo akronimów. Nawet samo słowo akronim brzmi trochę tajemniczo jak mu się bardziej przyjrzeć. Ale o co chodzi z tym DRY? Jest to skrót od słów Don’t Repeat Yourself. Nie trzeba wiele tłumaczyć, o co chodzi. Kluczowe w tej zasadzie jest to, aby pisać kod w taki sposób, aby nie trzeba było kopiować takiego samego bądź bardzo podobnego kodu. Jak myślisz… czy powinniśmy się kurczowo trzymać tej zasady?

Dlaczego tak?

Dobre praktyki mówią o wydzielaniu małych reużywalnych metod tak, aby nie trzeba było kopiować kodu. W idealnym świecie żaden większy kawałek kodu nie powinien być zduplikowany w obrębie jednej aplikacji. To bardzo dobre podejście i jak najbardziej powinniśmy tak tworzyć kod, aby jego części były tak zbudowane, aby można je było wykorzystać w innych miejscach. To trochę jak z niektórymi częściami samochodowymi pasującymi do wielu marek lub uniwersalnym pilotem do telewizora.

Dlaczego nie?

Często zdarza się w aplikacjach, że ktoś przesadzi z podejściem do reużywalności kodu i buduje bardzo skomplikowane generyczne rozwiązanie. Nie od dziś wiadomo, że coś, co jest do wszystkiego, jest do …

Budowanie generycznych rozwiązań powoduje, że kod przestaje być elastyczny i nietypowa zmiana biznesowa może wprowadzić bardzo dużo zamieszania do aplikacji i wywołać dużą frustrację wśród developerów.

Brak odporności na zmiany takich generycznych rozwiązań dobrze widać w projektach prowadzonych w podejściach zwinnych. Tam chyba żadne supergeneryczne rozwiązanie nie przetrwało próby czasu.

Podsumowanie

Odpowiadając na pytanie z tytułu, zachowam się jak rasowy konsultant i odpowiem “To zależy!”. Podejście do tego problemu zależy od wielu czynników. Jeden programista powie, że DRY trzeba stosować na każdym kroku, a inny powie, żeby nie stosować wcale. Nie no, ogólnie to zdecydowana większość się stosuje do tego. Moje doświadczenie podpowiada, aby nie wypływać za daleko na głębokie wody generyczności. Lepiej pozostać na suchym lądzie, ze swoimi małymi metodami i zrozumieniem, że duże ilości skomplikowanego kodu nie uczynią projektu lepszym. Najważniejsze w tym wszystkim jest zdrowe podejście i unikanie przewidywania, co się wydarzy w przyszłości, tylko budowanie rozwiązania na tu i teraz. Wtedy raczej nie przyjdzie nam do głowy budowania czegoś zbyt skomplikowanego i rzekomo do wszystkiego.

Jeśli artykuł Ci się podobał, zapraszam do polubienia profilu na facebooku oraz obserwowania na instagramie. Zapraszam również do grupy Wsparcie w programowaniu i zadawania pytań oraz do kontaku.

Jak rozpoznać solid(ny) kod?

Architektura systemów to nie jest najprostsze zagadnienie. Zadanie architekta jest trudne. Trzeba niczym Gary Kasparov przewidywać kilka kroków do przodu co się wydarzy, aby poprawnie zacząć. O tym jak pisać solidny, czysty i poprawny kod powstało już wiele książek.

Solidny kod to przede wszystkim kod napisany w prosty i czytelny sposób. Tu pojawia się reguła KISS mówiąca o tym, aby utrzymać kod maksymalnie prostym. Oprócz tego ważne, aby kod był utrzymywalny. Co to oznacza? A no to, że trzeba pisać kod tak, żeby za pół roku nie płakać podczas dodawania nowych funkcji do systemu.

Co zatem dokładnie zrobić, aby kod wyglądał tak, jak należy? Warto zacząć od postaw.

SOLID – to akronim stworzony z pierwszych liter zasad, którymi powinniśmy się kierować, pisząc kod.

Single Responsibility Principle

Powyższa reguła mówi, aby jednostka kodu była odpowiedzialna tylko za jedną rzecz. Co mam na myśli pisząc “jednostka kodu”? Zdania są podzielone odnośnie tego co powinno pełnić pojedynczą rolę. Jedni mówią, że to klasa ma pełnić tylko jedną funkcję, a inni mówią, że to metody w klasie powinny działać w ten sposób. Jak to bywa w programowaniu, prawidłowych odpowiedzi jest kilka. Ja proponuje podchodzić do tego po prostu racjonalnie.

Dla przykładu, jeśli mamy klasę, która jest odpowiedzialna za obsługę plików, to niech ona zajmuje się tylko i wyłącznie obsługą plików. Jeśli chcemy tej klasy użyć do tworzenia plików tekstowych i struktury katalogów to niech będą do tego stworzone osobne metody, a nie jedna.

Zamiast:

class FileManager {
 void createDirectoryStructureAndTextFile(String path, String file){

 }
}

Być może lepiej:

class FileManager {
 void createTextFile(String path, String file){

 }

 void createDirectoryStructure(String path){

 }
}

Dodatkowo warto zainteresować się podejściem DDD do tworzenia systemów. Dobrze przeprowadzona analiza w tym modelu pozwala zbudować system, w którym obszary biznesowe będą od siebie oddzielone jakimś fizycznym bytem, spełniając przy tym pierwszą zasadę SOLID na nieco wyższym poziomie.

Open-Close Principle

Reguła open-close z solid mówi o tworzeniu kodu otwartego na rozszerzanie a zamkniętego na zmiany. Oznacza to wymaganie tworzenia kodu w taki sposób, aby w przypadku dodawania nowej funkcjonalności nie było konieczności modyfikacji istniejących elementów.

Istnieje wiele metod pisania rozszerzalnego kodu i chyba większość z nich opiera się o zdrowy rozsądek i doświadczenie, ale jeden ze wzorców projektowych również nam w tym pomoże. Chodzi mi o wzorzec strategia.

Przeanalizujmy kod do walidacji danych wejściowych. Najpierw wersja, która wymusza na nas modyfikację klasy.

Piszemy pierwszą walidację – sprawdzanie czy użytkownik podał e-mail.

class UserDataValidator {
 public void validate(User input)throws ValidationException {
    if(input.getEmail()==null || input.getEmail().lenght()==0){
     throw new ValidationException("Email");
    } 

 }
}

Teraz załóżmy sytuację, że jakiś czas później musimy dodać kolejne sprawdzenia np. czy wiek jest większy niż 16 oraz, czy hasło ma przynajmniej 10 znaków.

class UserDataValidator {
 public void validate(User input)throws ValidationException {
    if(input.getEmail()==null || input.getEmail().lenght()==0){
     throw new ValidationException("Email");
    } 
    if(input.getAge()<=16){
     throw new ValidationException("Age");
    } 
    if(input.getPassword().lenght()<10){
     throw new ValidationException("Password too short");
    } 
 }
}

Jak widać, trzeba było zmodyfikować istniejącą klasę i tak będzie za każdym razem, gdy będzie konieczność dodawania nowych walidacji.

Teraz uczyńmy ten kod zgodnym z Open-Close principle. Zacznijmy od przygotowania interface dla naszej strategii.

interface UserDataValidator {
 void validate(User input)throws ValidationException;
}
class EmailValidator implements UserDataValidator {
  void validate(User input)throws ValidationException {
    if(input.getEmail()==null || input.getEmail().lenght()==0){
     throw new ValidationException("Email");
    } 
  }
}

Ten mechanizm użyjemy w następujący sposób.

class UserService {
  private UserDataValidator validator = new EmailValidator();

  public void createUser(User input){
    validator.validate(input);
  }
}

Mamy już walidację e-maila. Teraz dodajmy kolejne walidacje, wystarczy, że dopiszemy kolejne klasy.

class AgeValidator implements UserDataValidator {
  void validate(User input)throws ValidationException {
    if(input.getAge()<=16){
     throw new ValidationException("Age");
    } 
  }
}
class PasswordValidator implements UserDataValidator {
  void validate(User input)throws ValidationException {
    if(input.getPassword().lenght()<10){
     throw new ValidationException("Password too short");
    } 
  }
}

Teraz musimy zmodyfikować miejsce użycia walida torów, aby można było korzystać z wielu.

class UserService {
  private List<UserDataValidator> validators = List.of(
   new EmailValidator(),
   new PasswordValidator(),
   new AgeValidator()
  );

  public void createUser(User input){
    validators.forEach(v -> v.validate(input));
  }
}

W tym momencie dodanie nowego walidatora będzie wymuszało dodanie go do listy i modyfikację klasy UserService. Zmieńmy to w taki sposób, aby to nie było konieczne. Jedyne co trzeba zrobić to przekazać listę walidatorów przez konstruktor.

class UserService {
  private final List<UserDataValidator> validators;

  public UserService(List<UserDataValidator) validators){
   this.validators = validators;
  }

  public void createUser(User input){
    validators.forEach(v -> v.validate(input));
  }
}

//użycie
UserService userService = new UserService(List.of(
   new EmailValidator(),
   new PasswordValidator(),
   new AgeValidator()
  ));

Jak widać, kod w tym momencie jest dość odporny na modyfikację. W przypadku modyfikacji i tak coś trzeba będzie zmienić, ale będzie to tylko dodanie klasy do listy walidatorów. W przypadku korzystania z frameworku Spring nawet to nie będzie konieczne, to narzędzie zrobi tę operację za nas automatycznie.

Zapisz się na newsletter, aby otrzymywać informacje o nowych artykułach oraz inne dodatki.

Liskov Substitution Principle

LSP to według mnie najtrudniejsza reguła do zrozumienia ale bardzo łatwa do wdrożenia. Mówi ona o tym, że obiekty, które stanowią podtypy jakiejś klasy powinny dać się w łatwy sposób zastąpić ich superklasą (typem bazowym) bez popsucia aplikacji. To wymaga, aby obiekty podklas zachowywały się w taki sam sposób jak obiekty typu bazowego. Można to osiągnąć poprzez stosowanie kilku zasad przypominających design by contract.

Pokrótce zasady te mówią o tym, aby w przypadku nadpisywania metod zachować te same typy przyjmowanych parametrów i te same typy zwracane (lub typ pochodny od typu zwracanego w metodzie znajdującej się w klasie bazowej).

Interface Segregation Principle

ISP to moja ulubiona zasada ze zbioru solid. Mówi ona o segregowaniu interfejsów na potrzebny konsumentów. Dla przykładu opiszę abstrakcyjny przypadek, który zawsze opisywałem na swoich pierwszych rozmowach kwalifikacyjnych.

Załóżmy, że mamy klasę Child oraz klasy Teacher i Parent. Odpowiedzialnością dziecka jest zarówno uczenie się w szkole tego co zaleci nauczyciel jak i słuchanie tego co mówią rodzice. Rodzic inaczej będzie się komunikował ze swoim dzieckiem niż nauczyciel, wiec powinni oni mieć udostępnione inne wersje interfejsów mimo, że rozmawiamy o tym samym człowieku.

Zasada Interface Segregation Principle bardzo dobrze wpasowała się w architekturze heksagonalnej, gdzie dany moduł udostępnia wiele metod poprzez implementację wielu różnych interfejsów zwanych w tej architekturze portami. Inne moduły korzystające z tego modułu, posługują się portami, a więc zbiorem metod, które są im potrzebne. Mimo że implementacja danego portu (adapter) może fizycznie zawierać o wiele więcej metod, udostępnione będą tylko te, które znajdują się w danym interfejsie (porcie).

Te zasada w dużej mierze pozwala nam na utrzymanie porządku w aplikacji oraz pomaga w zachowaniu hermetyzacji kodu.

Dependency Inversion Principle

Moduły wysokiego poziomu nie powinny zależeć od modułów niskiego poziomu. Oba powinny zależeć od abstrakcji.

Abstrakcje powinny być zależne od detali. Detale powinny być zależne od abstrakcji.

Powyższe zdania są stwierdzeniami Wujka Boba, który słusznie zauważa, że pisząc aplikacje, powinniśmy posługiwać się abstrakcją, a nie konkretną implementacją. Myśląc w sposób abstrakcyjny, dużo prościej będzie nam budować elastyczne systemy, w których kawałki kodu (moduły) są łatwo wymienne.

Podsumowanie

W stosowaniu powyższych zasad ważne jest zdrowe podejście do tematu, a nie kurczowe trzymanie się wszystkich reguł spisanych w internecie. Solid to zbiór reguł, który powinien być znany każdemu programiście. Reguły solid pomagają pisać kod z myślą o przyszłości i kolejnych zmianach dlatego jest tak ważne i nie wyobrażam sobie, aby ktoś piszący kod komercyjnie nie znał tych zasad. Z biznesowego punktu widzenia pisanie kodu otwartego na łatwe modyfikacje zmniejsza koszt prowadzenia utrzymania aplikacji i po prostu prowadzi do oszczędności.

Pisząc solidny kod, pomagasz nie tylko organizacji poprzez oszczędności pieniędzy wynikające w łatwiejszego utrzymania, pomagasz również swoim kolegom i koleżankom, którzy w przyszłości będą musieli utrzymywać napisany przez Ciebie kod.

Jeśli artykuł Ci się podobał, zapraszam do polubienia profilu na facebooku oraz obserwowania na instagramie. Zapraszam również do grupy Wsparcie w programowaniu i do kontaku.

Mikroserwisy – Czy na pewno ich potrzebujesz?

Mikroserwisy w ostatnich kilku latach są postrzegane zarówno przez developerów, jak i organizacje jako bardzo sexy podejście do tworzenia aplikacji. Dlaczego tak się dzieje? Mikrousługi są lekkie, stworzone przeważnie w nowoczesnych technologiach, szybkie oraz łatwe w utrzymaniu. Ale co stoi z drugiej strony? Czy są ciemne strony tego podejścia?  Książka o ekonomii „Co widać, a czego nie widać”, Frederika Bastiata, uświadomiła mi, że w IT również trzeba zaglądać w te zacienione miejsca, aby podejmować świadome decyzje.

Architektura mikroserwisowa bazuje na koncepcji wydzielania małych niezależnych części kodu z większej aplikacji. W systemach monolitycznych często takie wydzielenie kodu sprowadzane było do stworzenia nowego pakietu lub modułu w aplikacji. Taki moduł finalnie uruchamiany był razem z innymi modułami na serwerze aplikacyjnym oraz traktowany jak jedna aplikacja. Mikroserwisy, w przeciwieństwie do tego podejścia, uruchamiane są niezależnie. Każdy moduł aplikacji uruchomiony jest jako osobna aplikacja, często z własną bazą danych, na własnym serwerze. Taka architektura dostarcza nam ogromną ilość zalet, ale może również stać się dla naszego projektu ogromnym obciążeniem. Jaka zatem jest odpowiedź na pytanie zadane w tytule? Otóż… to zależy. W tym tekście opiszę, z czym wiąże się tworzenie aplikacji w architekturze mikroserwisowej.

Architektura mikroserwisowa

Zerknijmy na te mikroserwisy

Gdy chcemy stworzyć aplikację w takiej architekturze, będziemy potrzebować kilku dodatkowych narzędzi. To one uczynią naszą infrastrukturę otwartą na skalowanie. 

  • Na początek potrzebujemy service discovery. Jest to wzorzec, który mówi, o potrzebie posiadania jednego miejsca, w którym każda mikroaplikacja będzie mogła się zarejestrować, aby inne aplikacje wiedziały, pod jakim adresem się znajduje. W rozwiązaniu tego zagadnienia pomogą nam narzędzia takie jak Kubernetes, Consul, Eureka lub inne dedykowane API dostępne w rozwiązaniach chmurowych.
  • Aby móc wygodnie zarządzać konfiguracją poszczególnych usług, możemy wdrożyć config serwer. Frameworki takie jak Spring wspierają ten mechanizm. Wystarczy stworzyć nową usługę i przy pomocy odpowiedniego pliku konfiguracyjnego sprawić, że każdy mikroserwis będzie pobierał swoje konfiguracje z jednego miejsca. Pliki konfiguracyjne mogą być przechowywane jako fizyczne pliki na serwerze lub możemy skorzystać z systemu kontroli wersji GIT. 
  • API gateway to kolejny element naszej mikrousługowej układanki. Aplikację budujemy po to, aby ktoś mógł z się z nią skomunikować. Aby to zrobić, dobrą praktyką jest stworzenie jednego punktu wejścia do systemu, który przekieruje ruch w odpowiednie miejsce. API gateway zatem będzie pełnił nie tylko rolę proxy, ale może się również dobrze sprawdzić jako load-balancer.
  • W większości przypadków będziemy potrzebować systemu, który odpowiada za uwierzytelnienie ruchu przechodzącego przez nasz system. 
  • Dodatkowe sprawy, o które trzeba zadbać w takiej architekturze to: odpowiednie zunifikowane logowanie błędów, śledzenie wiadomości przepływających przez system oraz monitoring aplikacji.
Ja pokazujacy na swoją głowę

Jak widać, zanim zaczniemy prawdziwy happy-coding aplikacji, musimy sporo nagimnastykować się z konfiguracją infrastruktury. Dodatkowo, aby wdrożyć taki system na serwerze i móc go łatwo utrzymywać, potrzebujemy narzędzia do orkiestracji takiego jak np. Kubernetes, którego również trzeba dostosować do naszych potrzeb.

Zalety

  • Możliwość wdrażania części aplikacji. Architektura mikroserwisowa, dzięki posiadaniu niezależnie działających usług, pozwala na wdrażanie części funkcjonalności bez potrzeby zatrzymywania systemu. Dzięki temu unikamy przestojów aplikacji. W najgorszym przypadku tylko niektóre funkcje systemu przestaną na chwilę działać. Dodatkowo downtime systemu będzie niższy niż w przypadku monolitów, ponieważ nie uruchamiamy na raz całego kodu aplikacji, a jedynie małą jego część.
  • Możliwość zwiększenia wydajności. Oprócz tego, że każdą usługę możemy uruchomić na osobnych maszynach, co już jest dużym usprawnieniem, mamy możliwość skalowania części aplikacji. Gdy któryś z serwerów ma dużo większe obciążenie niż pozostałe, możemy tę samą część uruchomić więcej niż jeden raz. Równomierne obciążenie serwerów zapewni wdrożony load-balancer.
  • Łatwość zrozumienia. Dzięki zwiększonej granulacji w systemie wdrożenie nowych programistów do pracy z mikroserwisami jest dużo prostsze niż w przypadku monolitu.
  • Większa izolacja błędów. Błąd w jednym mikroserwisie przeważnie nie wpływa na działanie pozostałych serwisów.
  • Możliwość zastosowania różnych technologii. Zespoły piszące aplikację mogą tworzyć każdą mikrousługę w innym języku. Ważne jest, aby wszystkie mikroserwisy komunikowały się ze sobą w ten sam sposób.

Wady

  • Mikroserwisy wymagają dokładnego przemyślenia i starannego zaprojektowania. Podczas projektowania należy dobrze przemyśleć, jak będzie odbywać się komunikacja w systemie. Ważne, aby unikać sytuacji, gdy funkcjonalność wymagająca transakcji wykonuje się sekwencyjnie w kilku serwisach. Nie jest to proste zadanie. Gdy okaże się, że musimy zbudować taki mechanizm, trzeba dobudować dodatkowe mechanizmy takie jak Two-Phase-Commit lub implementacja wzorca Saga. To dodatkowo komplikuje implementacje.
  • Więcej usług oznacza więcej zasobów potrzebnych, aby uruchomić aplikację, a co za tym idzie, większe koszta.
  • Bardziej skomplikowana architektura w porównaniu do monolitu. Obecność wymienionych wcześniej dodatkowych narzędzi oraz mechanizmów czyni architekturę mikroserwisów bardziej skomplikowaną.
  • Autoryzacja i uwierzytelnienie w rozproszonych systemach. To zagadnienie jest całkiem proste, dopóki nasz kod i wszystkie żądania mamy zamknięte w jednej fizycznej aplikacji. W przypadku systemów rozproszonych musimy zadbać o dużo mocniejsze zabezpieczenia, ponieważ usługi będą przesyłały żądania między sobą. Dodatkowo każda usługa musi „wiedzieć”, kto wykonuje zapytanie i, czy w ogóle może je wykonać.
  • Utrudnione śledzenie błędów. Jako że każdy mikroserwis generuje swój zestaw logów, to w przypadku problemów trzeba przejrzeć więcej plików i porównać z logami z innych serwisów. Aby ten proces ułatwić, stosujemy tracing, ale nadal proces przeglądania logów bywa mozolny.
  • Globalne testowanie end-to-end jest trudne. W przypadku monolitu po prostu uruchamiamy aplikację i uruchamiamy testy. W przypadku mikroserwisów wymagane jest odpowiednie uruchomienie wielu mniejszych aplikacji, co może sprawiać problemy z ich orkiestracją.
  • Cost per line przy małym systemie jest duży. Na początku trzeba dużo rzeczy skonfigurować i napisać sporo kodu boilerplate, zanim wystartujemy z developmentem. W monolicie koszt linii kodu jest mały na początku, w miarę rozrastania się systemu koszt się zwiększą, linie kosztów przecinają się bardzo daleko.
  • Pojawiają się problemy typu shared libraries vs. copy-paste. Z jednej strony zasada DRY (Don’t repeat yourself) mówi o wydzielaniu części wspólnych, lecz doświadczenia programistów często mówią o unikaniu współdzielonych bibliotek w mikrousługach na rzecz starego dobrego copy-paste.

Zapisz się na newsletter, aby otrzymywać informacje o nowych artykułach oraz inne dodatki.

Jeśli nie mikroserwisy, to co?

Codementor z zarówką nad głową.
  • Sharding bazy danych. W przypadku gdy system staje się mniej wydajny i szybkość zapisu w dużej mierze jest podyktowana szybkością operacji na bazie danych, to być może wystarczy skorzystać ze skalowania horyzontalnego Twojego źródła danych.
  • Skupienie się na wydajnych algorytmach – uświadamianie zespołów developerskich na temat złożoności obliczeniowej. W projektach IT często bywa tak, że odpowiedzialność za jakość jest nieco rozmyta. Programiści nie czują się w 100% właścicielami swojego kodu i po prostu budują rozwiązania wystarczające, nie skupiając się na optymalizacji algorytmów. Ciągłe uświadamianie członków zespołu oraz budzenie w nich poczucia odpowiedzialności za napisany kod może przyczynić się do znacznego zwiększenia nie tylko jakości kodu, ale i wydajności.
  • Podejście hybrydowe. Być może zamiast budowania całej aplikacji w architekturze mikroserwisowej wystarczy wydzielić z monolitu tylko niektóre kawałki aplikacji, które wymagają szybszego działania. 

Podsumowanie

Jak widać, mikroserwisy mogą wnieść wiele dobrego, ale również mogą stać się sporym obciążeniem. Jeśli nie masz zamiaru przetwarzać ogromnej ilości danych w projekcie albo zespół developerski składa się z kilku programistów, prawdopodobnie nie potrzebujesz wdrażać u siebie tak złożonych rozwiązań.

Bardzo dobrym podejściem może być zaczynanie od architektury monolitycznej. W miarę rozwoju systemu wydzielenie niektórych części systemu wyniknie naturalnie i raczej wydzielimy je słusznie i w odpowiedni sposób. Zaczynając nowy projekt, nie jesteśmy pewni, czy wydzielanie niektórych usług jest konieczne. Mikroserwisy w tym momencie mogą okazać się nie najlepszym wyborem. Aby zapewnić dobrą organizację kodu w monolicie i ułatwić późniejsze wydzielanie odrębnych usług, warto skorzystać z architektury heksagonalnej.

Przejście na architekturę mikroserwisową w istniejącej aplikacji również należy dokładnie przemyśleć. Istnieje szereg usprawnień, które powinniśmy rozważyć przed wdrożeniem tak skomplikowanej architektury.

Podsumowując, jeśli budujesz rozwiązanie dla małej firmy, start-upu lub system nie będzie ogromy, to raczej mikroserwisy nie będą dobrym rozwiązaniem. Dobrze zaplanowany modularny monolit na początek to bardzo trafny wybór.

Codementor z pieniedzmi klienta.

Ważne, aby w pierwszej kolejności dokładnie przeanalizować wymagania, biorąc pod rozważanie wiele czynników. Gdy w grę wchodzą pieniądze klienta, należy dobrze przemyśleć wszystkie aspekty, aby zaproponować rozwiązanie idealnie dopasowane do budżetu i potrzeb. Na etapie projektowania warto skorzystać ze świeżego spojrzenia architektów z innych zespołów, to pozwala na zaprojektowanie systemu w taki sposób, aby nie tylko był dobry tu i teraz, ale również służył klientowi w przyszłości z uwzględnieniem minimalnych kosztów.

Każdy z nas uwielbia nowe i ciekawe technologie, ale wynik analizy nie zawsze mówi, że to, co jest trendy, jest odpowiednim rozwiązaniem w danym przypadku. Jeśli nie chcemy być zespołem przytłoczonym przez wielką i ciężką machinę mikroserwisów, to warto na początek rozważyć inne lżejsze rozwiązania.

Jeśli artykuł Ci się podobał, zapraszam do polubienia profilu na facebooku oraz obserwowania na instagramie. Zapraszam również do grupy Wsparcie w programowaniu i do kontaku.