Shiju Varghese
Shiju VargheseConsulting Solutions Architect / Consultant & Trainer on Go

Bagaż Javy, czyli największa przeszkoda w używaniu Go

Dowiedz się, dlaczego doświadczonemu programiście Javy trudno idzie przestawienie się na język Go oraz sprawdź, jak to przeskoczyć.
13.11.20196 min
Bagaż Javy, czyli największa przeszkoda w używaniu Go

Pracowałem jako konsultant i trener języka programowania Go oraz architektury systemów rozproszonych, a także byłem team leaderem wielu zespołów programistów, które używały Go do budowy swoich systemów. Współpracowałem ze startupami, organizacjami średniej wielkości i większymi przedsiębiorstwami. Oprócz współpracy z niektórymi większymi graczami (nie ze wszystkimi, ale w większości przypadków), ścieżka adaptowania do Go w pracy, była bardzo przyjemnym doświadczeniem.

Kiedy uczę początkujących inżynierów oprogramowania, szybko załapują Go i zaczynają pracę nad budowaniem produktu w taki sposób, jak robią to doświadczeni inżynierowie. Ponieważ Go jest bardzo prostym i minimalistycznym językiem, ścieżka nauki jest bardzo łatwa, co jest naprawdę pomocne dla firm rozpoczynających projektowanie produktów. Zaletą mniej doświadczonych programistów jest to, że mają mniejszą ilość bagażu programistycznego doświadczenia, dzięki czemu są gotowi zaakceptować i przyjąć do wiadomości to, czego się ich uczy.

Niebezpieczne podejście do używania Go z bagażem Javy

Mentorowanie większych przedsiębiorstw o Go, było nierzadko trudną pracą. Główną przyczyną był ich bagaż związany z wcześniej używanymi technologiami. Większość tych zespołów wyrosła na używaniu Javy Enterprise i przy nauce Go szukają tego, co robili w Javie - zarówno w języku, jak i sposobie, w jaki budowali aplikacje Java. 

Miałem doświadczenia, w których zespoły już na początku szukały IoC w Go lub zamiennika środowiska Spring Boot, zanim zdążyli nauczyć się podstaw języka.

Wielu inżynierów Javy, szczególnie tych doświadczonych, najpierw szuka sposobu pisania wzorców projektowych Gang of Four i wzorców używanych w systemach enterprise w Go. Chcą napisać kod w Go dokładnie tak samo, jak pisali go w Javie. Zaczynają używać Go jako nowego popularnego języka, nie próbując nawet poznać jego możliwości. Nie traktują go jako “pełnego” języka. Uczą się Go bez pasji do Go. Ktoś na stanowisku decyzyjnym w organizacji postanowił zlecić używanie Go w nowych projektach lub zażądał tego klient. Albo jest hype na Go. Otóż to. Dochodzi do wybrania technologii, tylko dlatego, że jest nowa.

Takie podejście jest bardzo niebezpieczne. Decydenci mogą wybierać Go z  najlepszych i przemyślanych pobudek, ale dopóki zespoły będą go wdrażały bez zrozumienia i zaangażowania, może to sprawić wiele problemów. Nawet kiedy prowadzę warsztaty z Go, niektóre z tych osób (te, które mają problemy z nastawieniem) nie są otwarte na pełne zrozumienie tego języka i odrzucają pisanie idiomatycznego kodu w Go. Chcą pisać w Go w “javowy” sposób.

Nie jest dobrym pomysłem szukanie ekwiwalentów Javy w Go. Kiedy uczysz się interfejsów Go, które są zaimplementowane niejawnie, możesz potraktować to jako fajną możliwość języka, ale też pomyśleć, że to problem, patrzac przez pryzmat jawnie implementowanych interfejsów Javy. Kiedy patrzysz na system typów Go z perspektywy Java, może to sprawić wiele problemów

Jeśli starasz się odnaleźć drugą Javę w Go, to pewne, że uczysz się tego języka z bardzo nieodpowiednim nastawieniem, myśląc o tworzeniu oprogramowania, Twój sposób myślenia będzie nadal krążył wokół Javy, zamiast już wokół Go. Każdy język programowania ma swoje mocne i słabe strony, na podstawie których wybierasz język w oparciu o swoje podejście i filozofię programowania.

Zrozum filozofię Go

Języki programowania, narzędzia, frameworki, a nawet podejścia do architektury są zaprojektowane do rozwiązywania pewnego rodzaju problemów. Wiele z tych języków i narzędzi to rzeczy ewolucyjne, które powstały na bazie przeszłych doświadczeń i wyzwań, przed którymi stawaliśmy, rozwiązując niektóre problemy. Tak więc kiedy projektujemy nowe rzeczy, oczywiście bierzemy też pod uwagę problemy, które mieliśmy w przeszłości. Ale wszystko wokół ewoluuje. Nie ma nic trwałego. I dotyczy to również inżynierii oprogramowania.

Go został zaprojektowany z myślą o prostocie i pragmatyzmie. Nie dba o teorię języków programowania i intelektualne gdybania. Aby opanować ten język, najważniejsze jest oduczenie się wszystkiego, co wiesz o poprzednich i zgłębianie go jako świeżego języka programowania. Gdy się do tego zastosujesz, dostrzeżesz możliwości.

Kiedy uczyłem się Go 6 lat temu, byłem doświadczonym programistą i architektem w C#. Korzystałem z .NET od wersji beta. Kiedy spojrzałem na Go bez bagaży z C# i .NET, podekscytowałem się pragmatyzmem Go. Po kilku latach pisania systemów w Go, przyznaję, że często niepotrzebnie komplikowałem architekturę, projektując systemy w .NET..

System typów znakomicie wspierający typy definiowane przez użytkownika i podstawy współbieżności są najbardziej ekscytującymi elementami Go. Stany i zachowania są izolowane w typach zdefiniowanych przez użytkownika Go, w których po prostu definiuje się stany w treści struktury, a zachowania są dodawane później, gdy piszesz funkcje, które mogą być wywołane na tym typie. Interfejsy Go są implementowane niejawnie. Gdy podejdziesz do tych pragmatycznych funkcji języka ze świeżym spojrzeniem, możliwości staną przed Tobą otworem.

Należy pamiętać, że Go nie jest konwencjonalnym językiem programowania obiektowego. Dlatego implementacja w Go niektórych wzorców projektowych, stworzonych w erze typowych języków programowania obiektowego, może nie być dobrym pomysłem. Widziałem, że wielu programistów Javy szukało sposobu w Go do korzystania z wielu konwencjonalnych wzorców, których używali w Javie.

W świecie Go kwestia wzorców projektowych wygląda inaczej. Ze względu na prostotę Go, czasami będziesz musiał częściej klikać kopiuj/wklej w kodzie. Np. Go 1.13 nie obsługuje Generics, co oznacza, że możesz potrzebować crtl+C/ctrl+V w konkretnych scenariuszach. Tutaj prostota i lepsza wydajność wygrywa z funkcją Generics. Zrozumienie języka jest bardzo ważne, zanim zaczniesz w nim na serio programować.

Koncentracja na dobrych zasadach inżynierii oprogramowania

Kiedy mentoruję początkującym programistom, zawsze mówię im, żeby skupiali się na dobrych zasadach inżynierii oprogramowania, a nie na składni języka i gramatyce. Języki programowania zapewniają jedynie mechanizm pisania kodu przy użyciu jego gramatyki i semantyki. Nawet używając dobrego języka programowania, możesz napisać bardzo zły kod, jeśli nie masz odpowiedniej wiedzy.

Zauważyłem, że niektórzy ludzie są przywiązani do składni języka i określonych funkcji, a to stoi im na przeszkodzie w zrozumieniu pewnych rzeczy we właściwy sposób. Mówię ludziom: „Nie skupiaj się na składni. To największa pułapka, która uniemożliwia Ci dotarcie do istoty problemu i rozwiązania”. Kiedy patrzysz na interfejsy Go z barierą syntaktyczną, oczywiście trudno będzie Ci coś napisać w duchu Go. Kiedy się tego wyzbędziesz, interfejs stanie się magicznym narzędziem do pisania systemów skupiających się na testowalności i rozszerzalności.

Jeśli skupisz się na dobrych zasadach inżynierii oprogramowania, możesz napisać dobry kod w dowolnym języku, jeśli zrozumiesz filozofię tego języka. Zrozum zasady działania języka, którego używasz, a następnie dołóż do tego dobre zasady dotyczące tworzenia oprogramowania. Zapoznaj się z zasadami SOLID, a następnie naucz się tworzyć systemy oprogramowania oparte o clean architecture.

Podczas pracy nad produktem głównym celem jest rozwiązywanie problemów, a nie implementacja funkcji i wzorców językowych. Używasz ich, aby rozwiązać problem, pisząc kod idiomatyczny. Najpierw zrozum zakres problemu, a następnie pomyśl, jak za pomocą języka i jego narzędzi rozwiązać dane zagadnienie.

Gdy zaczniesz używać Go, ucz się pisać idiomatyczny kod w oparciu o zasady SOLID, z czystą architekturą. Pisanie kodu w Go w “javowy” sposób nie ma sensu, jeśli możesz po prostu użyć Javy. Pisząc aplikacje za pomocą Go, nie używaj zmiennych globalnych.

Jeśli używasz wolnych funkcji, działających na poziomie pakietu/zmiennych globalnych, lepiej stwórz strukturę, w której zdefiniujesz wszystkie stany i zależności, a następnie napisz metody tej struktury zamiast tworzyć wolne funkcje. Pozwala to odizolować zależności, a co za tym idzie, daje lepszą testowalność.

W tym celu można zdefiniować struktury w Go, w których można wprost zdefiniować zależności przez określone właściwości oraz napisanie odpowiednich metod. Możesz wprowadzać zależności w ramach kontraktu wprowadzonego przez interfejsy.

<p>Loading...</p>