Ludziom trudno jest zobaczyć szerszy obraz problemu bez poświęcania dużej ilości czasu i wysiłku. Dzieje się tak zwłaszcza podczas pracy z dużymi i złożonymi aplikacjami. Jakie są skutki uboczne moich zmian? Dlaczego ta linia tutaj wpływa na testy odległej części bazy kodu? Idealne lub kompletne rozwiązanie nie istnieje, ale Shopify wypuściło narzędzie, które prawdopodobnie pomoże Tobie i Twojemu zespołowi.
Wprowadzenie
Aby porozmawiać o PackwerkMusimy jednak najpierw wprowadzić kilka pojęć.
- Spójnośćodnosi się do miary tego, jak bardzo elementy w module lub klasie należą do siebie.
- Sprzęgłoodnosi się do poziomu zależności między modułami lub klasami.
- Graniceodnosi się do barier między kod. W tym przypadku granica kodu odnosi się do różnych domen w ramach tej samej bazy kodu.
- ModularyzacjaProces dzielenia systemu oprogramowania na wiele oddzielnych modułów, z których każdy działa niezależnie.
Problemy
Jak wiemy, Ruby nie zapewnia dobrego rozwiązania do egzekwowania granic kodu. Możemy określić widoczność, ale wszystkie zależności zostaną załadowane do globalnej przestrzeni nazw. W dużych lub monolitycznych aplikacjach ten brak granic powoduje następujące problemy.
- Niska spójność,
- Wysokie sprzężenie,
- Kod spaghetti.
Próbując modularyzować monolit Shopify i egzekwować granice, próbowali różnych rozwiązań, nie osiągając oczekiwanych rezultatów:
- Ustawianie stałych prywatnych,
- Ustalanie granic za pomocą klejnotów,
- Korzystanie z testów w celu zapobiegania powiązaniom między komponentami,
- Korzystanie z modulacji Ruby,
- Tworzenie mikrousług.
Mając całą wiedzę z poprzednich prób, postanowili stworzyć własne narzędzie: Packwerk.
Packwerk
Czym jest Packwerk?
Packwerk jest narzędziem analizy statycznej używanym do wymuszania granic między grupami Ruby pliki o nazwie pakiety.
Co to jest pakiet?
A pakiet to folder zawierający automatycznie ładowany kod. Shopify's zespół zachęca do stosowania najlepszych praktyk projektowych podczas tworzenia pakietów.
- Powinniśmy pakować razem rzeczy, które mają wysoką funkcjonalność spójność,
- Pakiety powinny być ze sobą stosunkowo luźno powiązane.
Rodzaje kontroli granicznych
Możemy egzekwować granice prywatności i zależności, sprawdzać naruszenia granic i zależności cyklicznych.
Packwerk w praktyce
Nie ma jednego konkretnego sposobu na ustrukturyzowanie lub zrestrukturyzowanie aplikacji podczas tworzenia pakietów. W tym artykule będziemy postępować zgodnie z podejściem sugerowanym przez
Stephan Hagemann w Stopniowa modularyzacja dla Ruby on Rails.
Wybierz projekt
Można utworzyć nowy projekt lub wybrać jeden ze swoich projektów. Zdecydowałem się użyć projektu open-source o nazwie CodeTriage. Ważne jest, aby wspomnieć, że potrzebujemy aplikacji Rails 6, ponieważ Packwerk używa Zeitwerk.
Inicjalizacja Packwerk
Najpierw musimy dodać gem do naszego pliku Gemfile w następujący sposób gem 'packwerk'
a następnie uruchomić pakiet
w konsoli. Następnie jesteśmy gotowi do zainicjowania uruchomionego gema packwerk init
.
Następnie zauważamy, że Packwerk wygenerował dla nas trzy pliki:
-
packwerk.yml
-
package.yml
-
inflections.yml
packwerk.yml jest plikiem konfiguracyjnym Packwerk gdzie zdefiniujemy między innymi pliki dołączone i wykluczone, listę ścieżek ładowania, zdefiniujemy plik fleksji;
package.yml jest plikiem konfiguracyjnym pakietu. W tym pliku dodamy konfigurację dla granic naszego pakietu. Każdy folder z package.yml zostanie rozpoznany jako pakiet przez Packwerk. To wszystko, Packwerk stworzył nasz pierwszy
i nazywamy go pakietem korzeń pakiet.
inflections.yml to miejsce, w którym umieścimy nasze niestandardowe fleksje i akronimy na wypadek, gdybyśmy ich używali.
Więcej informacji na temat plików i ich konfiguracji można znaleźć na stronie
Packwerk.
Właściwości Packwerk
Aby modularyzacja działała, potrzebujemy trzech podstawowych właściwości: nazwany kontenerjego zawartośći wyraźnie zależności na innych pojemniki. Zdefiniujmy więc te właściwości w Packwerk:
-
Nazwa: Nazwa pakietu to jego względna ścieżka z katalogu głównego
aplikacja.
-
Treść: Kiedy umieszczamy package.yml w folderze, wszystkie pliki w folderze są teraz zawartością pakietu.
-
Zależności: Możemy zdefiniować zależności od innych pakietów dodając klucz zależności do pliku package.yml.
Innym plikiem, który nie jest dołączany domyślnie, ale jest zalecany, jest README. Ważne jest, aby dostarczyć informacji na temat korzystania z pakietu.
Koniec odcinka I
Czytaj więcej
GraphQL Ruby. Co z wydajnością?
Szyny i inne środki transportu
Rails Development z TMUX, Vim, Fzf + Ripgrep