![Adam Banaszkiewicz - Programista Kontrowersyjny](/img/default-banner.jpg)
- Видео 14
- Просмотров 7 917
Adam Banaszkiewicz - Programista Kontrowersyjny
Польша
Добавлен 29 авг 2020
Chodź, pogadamy o architekturze, testach, programowaniu i problemach w bardzo kontrowersyjny, zawadiacki i zabawny sposób. Jeśli szukałeś wiedzy technicznej, którą możesz przełożyć na rzeczywistość to dobrze trafiłeś!
Warstwa Aplikacji - Cztery Warstwy #3
Warstwa Aplikacji przechowuje wszystkie przypadki użycia systemu. Każde polecenie zmieniające jego stan, oraz każde zapytanie zwracające informacje zapisane w tym systemie. Pokażę Ci dzisiaj jak wygląda ta warstwa, na jakie pytanie odpowiada, jaka jest jej odpowiedzialność oraz jak umieścić ją w kodzie.
Kod źródłowy znajdziesz na: github.com/adambanaszkiewicz/four-layers-of-application-example
01:23 Zacznijmy od kodu
02:51 Odpowiedzialność warstwy Aplikacji
04:32 Polecenia i Widoki
06:13 Umiejscowienie w kodzie aplikacji
07:15 Połączenie z innymi warstwami
07:59 Orkiestracja poleceń
09:09 Łapanie wyjątków
10:57 Lecimy do kodu
Kod źródłowy znajdziesz na: github.com/adambanaszkiewicz/four-layers-of-application-example
01:23 Zacznijmy od kodu
02:51 Odpowiedzialność warstwy Aplikacji
04:32 Polecenia i Widoki
06:13 Umiejscowienie w kodzie aplikacji
07:15 Połączenie z innymi warstwami
07:59 Orkiestracja poleceń
09:09 Łapanie wyjątków
10:57 Lecimy do kodu
Просмотров: 360
Видео
Prywatny projekt po godzinach - Warto?
Просмотров 2,4 тыс.Месяц назад
Stagnacja w projekcie? Nauczyłeś się już wszystkiego i brakuje Ci nowych wyzwań? Albo chciałbyś się rozwijać ale nie masz możliwości, a dobrze płatna posada zniechęca Cię do zmiany projektu? Opowiem Ci o tym dlaczego warto rozpocząć mały projekt po godzinach, jak znaleźć pomysł i jak w ogóle znaleźć na to czas. 00:37 Intro 01:03 Miejsce na popełnianie błędów 03:42 Prototypowanie 04:40 Nowe tech...
PHP 8.4 - Najważniejsze zmiany
Просмотров 523Месяц назад
PHP 8.4 nadchodzi, można już testować wersję Alpha, więc pora zapoznać się z najważniejszymi nowościami tej wersji języka. wiki.php.net/rfc/new_without_parentheses wiki.php.net/rfc/property-hooks wiki.php.net/rfc/deprecate-implicitly-nullable-types
Warstwa Domeny - Cztery Warstwy #2
Просмотров 6062 месяца назад
Domena steruje procesem biznesowym. Zawiera wszystkie warunki i reguły biznesowe które muszą być spełnione by wykonać jakąś operację. Pominięcie tej warstwy albo zlanie jej z resztą aplikacji powoduje, że kod zaczyna być trudny do zrozumienia i modyfikacji. Opowiem Ci czym jest warstwa Domeny, jak ją znaleźć, wyodrębnić i umiejscowić w kodzie aplikacji. Kod źródłowy znajdziesz na: github.com/ad...
Warstwa Infrastruktury - Cztery Warstwy #1
Просмотров 1,4 тыс.3 месяца назад
Mieszanie bazy danych z logiką biznesową? Standard c'nie? A może by tak zrobić refaktoring, i świadomie wyodrębnić infrastrukturę z logiki biznesowej? Pokażę Ci czym jest i jak identyfikować infrastrukturę w kodzie, jak świadomie jej używać i jakie zalety niesie ze sobą jawne zdefiniowanie warstwy infrastruktury w kodzie. Kod źródłowy z filmu znajdziesz tu: github.com/adambanaszkiewicz/four-lay...
Mocki, Mocki wszędzie... Jak się ich pozbyć?
Просмотров 6533 месяца назад
Pamiętasz ten moment, gdy zrobiłeś mały refaktoring i testy zaczerwieniły się, po czym wchodzisz sprawdzić co jest nie tak a tam połowa testu to Mocki? Refaktoring kodu nie powinien wpływać na testy, a jednak często tego wymaga. Opowiem Ci dzisiaj czym są Mocki i czemu są złe, dlaczego większość programistów ich używa oraz czym i jak je zastąpić, by nigdy więcej nie musieć babrać się w takich t...
Mapa Kontekstów? Panie, a na co to komu...
Просмотров 4864 месяца назад
Słyszałeś o Mapach Kontekstów, ale nie wiedziałeś z czym to się je? Ma tutaj wszystko jak na tacy! Co zawiera, jak się ją robi, na co zwrócić uwagę i do czego się przydaje w pracy nad projektem. Dodatkowo opowiem Ci o Narzędziu Deptrac, które w połączeniu z Mapą Kontekstów daje fajne zabezpieczenie utrzymania relacji modułów w ryzach. 00:00 Intro 00:58 Wstęp 02:20 Po kiego grzyba mi to? 05:46 M...
Kurs Event Storming | Trailer | kurseventstorming.pl
Просмотров 1037 месяцев назад
Kurs Event Stormingu dostępny już teraz na: kurseventstorming.pl
Cel i Zakres Big Picture Event Storming | kurseventstorming.pl
Просмотров 857 месяцев назад
Lekcja pokazowa: Cel i Zakres Big Picture Event Storming. Cały kurs znajdziesz na kurseventstorming.pl
Jako amator, hobbysta... przydałoby się parę słów o DI bo to _repo_ to na razie "under the hood"/"behind the scene"
Mógłbyś bardziej rozwinąć co masz na myśli? Czego byś potrzebował?
@@adambanaszkiewicz 14:54 metoda _addToCart_ korzysta ze zmiennej _repository_. _repository_ jak i kiedy zainicjowane, jak przekazane do _addTo_Cart_ tak żeby odpowiadało konkretnej instancji _MysqlCartRepository_ ? Na niewtajemniczonym w Clean Architecture robi to spore wrażenie ;)
Teraz rozumiem. Wszystko zależy od języka i frameworka w którym piszesz. W większości będzie to wyglądało tak samo, czyli definiujesz serwis z nazwą interfejsu, ale z instancją klasy. Symfony zrobi to w sumie za nas gdy zrobimy autowire i gdy jest tylko jedna implementacja interfejsu. Nie chciałem dodawać zbyt dużo szczegółów do repozytorium by go nie "rozwodnić" zbytnio. Napisz do mnie na LinkedIn albo na FB, pociągniemy temat dalej jeśli jesteś zainteresowany :)
@@adambanaszkiewicz Dzięki za odpowiedź. Roztrząsanie tego wątku w rzeczy samej zaciemniłoby jasność przekazu w materiale.
Prototypowanie, używanie nowych narzędzi, próbowanie nowych technologii i popełnianie błędów powinno odbywać się w ramach zatrudnienia w godzinach pracy :)
Masz rację... "powinno" :)
Jeżeli musisz robić prywatne projekty po godzinach do rozwoju to znaczy, że już przegrałeś i najwyższa pora zmienić prace. W 99% przypadków prywatny projekt nie da ci możliwości pracy "w skali" co automatycznie powoduje, że możemy sobie przetrenować rzeczy, które już na tym etapie wypluje dla nas Claude czy inne AI. Bezsensu.
Praca z AI nie zawsze jest możliwa - to zależy od projektu i ilości kodu. I tak, nie ma efektu skali w pracy po godzinach. Z drugiej strony, gdy jednocześnie myślisz o skali projektu i rozwiązaniu problemu, najzwyczajniej jedno z tych dwóch zostanie zrobione po łebkach.
No niby fajny podział i dobrze wytłumaczone, ale czy podział na application/domain/infrastructure faktyczenie ma sens i dobrze się z tym pracuje? Bo jeśli chce dodać jakiś nowy feature to muszę zmodyfikować każdą z tych warstw. Nie lepiej mieć package by feature i np. w packagu "orders" trzymać wszystkie klasy zwiazane z tą domeną i przy dodawaniu nowych funkcji otworzyć jeden taki pakiet a nie skakać po czterech?
W przypadku "package by feature" musisz sprostać jednemu wyzwaniu - w module z 30 features'ami, gdy część z nich używa tego samego kodu współdzieląc go, musisz znaleźć złoty środek na to by go nie duplikować, a mimo wszystko nadal trzymać wszystko podzielone per feature. Zgadzam się z tym, że przy dodawaniu feature musisz dotykać każdą z warstw, ale zwróć uwagę, że w warstwach UserInterface i Application jest w 90% to samo (kontroler i UseCase wyglądają bliźniaczo) więc robi się je w 15 minut. Reszta to domena i infrastruktura. Gdy masz wszystko w jednym katalogu możesz nieumyślnie zacząć mieszać odpowiedzialności klas przez co zacznie się robić chaos. Podział na cztery warstwy sprawdza się dobrze w nietrywialnych modułach (nie-CRUDach), ponieważ pozwala oddzielić odpowiedzialność za poszczególne rzeczy na poziomie folderów w projekcie. Projektowałem kilka systemów, które posiadały w wybranych modułach takie podziały i spisywało się idealnie. Warto jednak podchodzić do takiego podziału racjonalnie - jak do wszystkiego. To nie jest rozwiązanie uniwersalne, nie wszędzie będzie pasowało - nie ma rzeczy uniwersalnych. Być może zdarzą się przypadku, że nie będzie to miało sensu. Natomiast, wiedza o tych czterech warstwach, o ich odpowiedzialności, pozwala lepiej organizować klasy i relacje między nimi. Możesz nie mieć struktury czterech warstw w strukturze projektu, a mimo to nadal posiadać ten podział na poziomie klas - dzięki CQRS właśnie. Dodatkowo taki podział wspiera różnego rodzaju testy (jednostkowe, funkcjonalne, integracyjne) osobno na każdej z tych warstw. O tym będę robił osobny odcinek.
Genialne wideo, 2 główne pytania z którymi borykają się programiści: jak to nazwać i gdzie to wrzucić :p poleciał i sub i like!
Dziękuję, cieszę się że weszło :D Co do nazywania to siedzi mi z tyłu głowy osobny materiał "Czemu nie umiemy nazywać?" - Keep in touch :D
Nowy kanał a już zaproszenie do kursu? Jak chcesz zarobić to najpierw zdobądź uznanie i zgromadź społeczność, a później się okaże czy warto wydawać pieniądze ...
A możesz powiedzieć gdzie dostałeś zaproszenie? :) Jeśli na YT to przez proponowane filmy przez algorytm :)
Teraz WSZYSTKO rozgrywa się o to, aby trafić do mądrej firmy, z bardzo mądrym zarządem i z workami złota na inwestycje/ szkolenia. Dlatego ja się uczę, bo lubię (a chyba nawet jestem uzależniony od nauki), ale nie widzę żadnego długoterminowego sensu pracy w firmie, gdzie prezes jest zwykłym populistą, a zarobił na tym, że Tsunami IT zabierało ze sobą wszystkich i wszystko, ale ono się skończyło i rynek robi "pivota", więc pójście do takiej firmy, to strzał w kolano, bo wylecisz z rynku (właściciel jeszcze swoje zarobi i z głodu nie umrze- zamknie firmę i dobrze będzie żył; mieli farta [NIC WIĘCEJ], ale na farcie już nigdzie nie pojadą, ale jeszcze kawałek na oparach im się uda). I co mi z tego, że pójdę do IT do nieuków? Na jak długo będę miał pracę??? 1-2-5 lat??? A co później? Jeżeli chcesz się utrzymać na rynku, to idź TYLKO do mądrej firmy z bardzo mądrym zarządem (podpowiem- nie obniżają stawek, a wręcz przeciwnie, ale pod "nowy profil kandydata"). Jakie są realne stawki??? 50-100k/ msc, czyli tak jak na Zachodzie, bo takich ludzi NIE MA (robili projekty po godzinach, czyli stali się "wybitnymi inżynierami", a to już za mało).
A gdzie tam- zaraz skończy Ci się doba. Rozwijając umysł (a nie zdobywając doświadczenie z samego programowania) zwiększasz cenę swojej roboczogodziny (ale to nie takie proste) i wtedy idziesz do poważnej firmy z kompetentną kadrą menedżerską (czyli Zachód). I w ogóle będziesz użyteczny w przyszłości (chcesz wygrać z AI w "liczeniu"??? Jakim cudem??? Słaby pomysł...)
Wszystko w ramach recjonalnego pożytku. Nie wszystkim siedzenie po godzinach będzie się opłacało, zgadam sie. Jest to rozwiązanie raczej dla osób które nie mają innej możliwości a chcą się rozwijać.
@@adambanaszkiewicz ale to już nie ma sensu... Oczywiście tak było i w takim kontekście miało to rację bytu, ale... już nie ma :) Czy zaszkodzi? Pewnie nie, ale to już para w gwizdek, czyli strata czasu.
Na każdym projekcie czegoś się uczymy. Najlepiej uczymy się w praktyce. Prywatny projekt jest kluczowy według mnie w procesie nauki i rozwoju jako programista.
Ja mam kilka pobocznych projektów. Używam ich jako proof of concept moich pomysłów. Część przenoszę potem na produkcję w pracy i nie traktuję tego jako darmowe, bo oczywiście czas który poświęciłem został policzony tak jaki faktycznie był. Dzięki temu że to nie był projekt w pracy nie musiałem się martwić że wszystko popsuję lub potraktować code base jako piaskownica do nauki dla innych. Ta dowolność ułatwia mi utrzymanie zainteresowania i chęć do działania(motywację). Cieszę się z tego czego sam się nauczyłem.
kurwami? :O
Jakoś trzeba odreagować gdy coś nie idzie po naszej myśli :D
Super!!!! 💝💖💗💓💞💕💟💝💖💗💓💞💕💟💝💖💗💓💞💕💟💝💖💗💓💞💕💟💝💖💗💓💞💕💟💝💖💗💓💞💕💟💝💖💗💓💞💕💟 💝💖💗💓💞💕💟💝💖💗💓💞💕💟💝💖💗💓💞💕💟💝💖💗💓💞💕💟💝💖💗💓💞💕💟💝💖💗💓💞💕💟💝💖💗💓💞💕💟 💝💖💗💓💞💕💟💝💖💗💓💞💕💟💝💖💗💓💞💕💟💝💖💗💓💞💕💟💝💖💗💓💞💕💟💝💖💗💓💞💕💟💝💖💗💓💞💕💟 💝💖💗💓💞💕💟💝💖💗💓💞💕💟💝💖💗💓💞💕💟💝💖💗💓💞💕💟💝💖💗💓💞💕💟💝💖💗💓💞💕💟💝💖💗💓💞💕💟 💝💖💗💓💞💕💟💝💖💗💓💞💕💟💝💖💗💓💞💕💟💝💖💗💓💞💕💟💝💖💗💓💞💕💟💝💖💗💓💞💕💟💝💖💗💓💞💕💟
Żeby się nauczyć czegoś więcej, to tak. Ale biznesowo wychodzisz na tym jak Zabłocki na mydle. Nawet jak dzięki temu dostaniesz lepszą pracę, to na miejscu nie dostaniesz proporcjonalnie większej wypłaty do tego ile czasu spędzasz na kodowaniu po pracy względem ludzi "szanujących" swój czas po pracy.
Muszę się zgodzić, niestety to nie wpłynie bezpośrednio od razu na kwestie finansowe. Jest to kwestia rozwoju osobistego gdy nie mamy innej opcji w firmie a chcemy się rozwijać. Kwestie finansowe najszybciej wyjdą gdy zmienimy pracę, ale gdy można zmienić pracę to w tedy nie trzeba ogarniać projektu po godzinach bo rozwój jest w nowym projekcie :)
Jakbyś mówił o mnie :) ostatnio zacząłem swój własny projekt, ale ciężko znaleźć mi motywację do drugiej "pracy" po normalnej pracy. Chociaż Twój film sprawił że trochę bardziej się chce :)
Milo to słyszeć :) Z motywacja jest chyba ten problem, że traktujesz to jako drugą pracę :) Z mojej perspektywy to była frajda robienia czegoś innego niż w pracy, i pewna odskocznia od codziennego klepania kodu w legacy. Po wakacjach nawet tęskniłem aż wrócę do tego małego projektu bo tam robiłem to co lubię :)
Nie warto, już lepiej iść na spacer albo znaleźć inną pasję. Pozdrawiam. ;p
@@morelia9718 Gitara po pracy sprawdza się idealnie :)
Wszystko spoko, ale po co robić prywatny projekt, skoro codzienna praca i tak będzie bez sensu? Więc - róbcie prywatne projekty, próbujcie na nich zarobić. A pracę jak jest chujowa - zmieńcie.
Szacun za podejście. Jeśli ktoś jest w stanie zmienić pracę bo się nie rozwija to zdecydowanie najlepsza opcja :)
Wszystko pięknie, ale… Po pierwsze za taki projekt płaci się zdrowiem. Siedzenie po 10 godzin dziennie jest szkodliwe. Po drugie - owszem projekt nas uczy, ale wiedza w programowaniu szybko się dezaktualizuje. Właściwie wręcz nie warto siedzieć po godzinach z tego powodu. Po trzecie wreszcie - rozwój powinien być częścią pracy. Robić POCe, nowe moduły, a nie po godzinach. Czy mechanik po godzinach eksperymentuje na własnym aucie żeby się doszkalać? Czy lekarz na rodzinie się trenuje albo fryzjer?
Wszystko z głową, masz rację. Nie namawiam do siedzenia po 10 godzin bo to tortury są :D Jeden rabin powie tak, drugi inaczej. Rozumiem Twój punkt widzenia i zdaje sobie sprawę że są takie zakamarki IT gdzie wiedza szybko się dezaktualizuje. Jeśli jednak dana osoba nie może się rozwijać w inny sposób to jest to jedyna opcja by liznąć czegoś nowego. Ale, wszystko w granicach zdrowego rozsądku, na tyle ile komuś pasuje :)
@@adambanaszkiewicz myślę, że jeśli na przykład dana technologia kończy cykl życia i musimy się przesiąść na coś nowego to będzie dobrze posiedziec nad jakimś projektem, natomiast i tak z reguły firmy chcą brać kogoś kto już w pracy to robił. Ale dla samego doskonalenia umiejętności uważam to za przesadę. A już szczególnie w tym momencie, gdy rynek tak siada, że może się okazać że za parę lat będziemy zarabiać dwie średnie krajowe. Wtedy szkoda pleców i dupy na takie wyniki. Nie neguje mimo wszystko rozwoju, ale nie powinno być normalnością siedzenie rok po roku nad prywatnymi projektami żeby zostać na rynku pracy. To jest patologia. Lekarze może dużo pracują, ale chyba nikt nie wierzy, że czytają po godzinach Lancet. Raczej robią dwa etaty.
Akurat z mechanikiem nie trafiłeś, bo większość ludzi z tego fachu klepie graty w wolnym czasie. Głównie dla przyjemności, nie dla rozwoju, ale na pewno przy okazji się czegoś uczą.
@@tomek3880 no jak dla przyjemności, to inna sprawa. Ja mówiłem o robocie dla rozwoju, z etosu pracy i obowiązku.
warto sluchac swojego ciala - jak czujesz sie na to gotowy to działaj.. a jak nie, to ciul z tym - raz sie zyje
a tam, warstwy ;p na co to komu? ;p wszystko do jednego katalogu ;p
Jesteś Włochem, że aż tak bardzo lubisz spagetti? :D
@@adambanaszkiewicz nie. Jestem ze śląska więc lubie burdel i patologie :D xD
02:48 - czyli naoglądaliście się Sobótki na vhs ? :P pozdrawiam serdecznie :)
Sobótka na VHS... Nie sądziłem że on aż tak wiekowy jest :D Może nie od Sobótki tylko generalnie temat zaczął być popularny w firmie a gdy nadarzyła się okazja to skorzystaliśmy :)
ja zacząłem swój side project. Niestety, brak motywacji do pracy po pracy, pomimo tego, że nie jest to projekt do szuflady a coś co może realnie zarabiać. Na szczęście wpadła mi ostatnio jedna influencerka, która potrzebowała na szybko pomocy a wyszło tak, że zostałem z nią na dłużej :) akurat aplikacja jaką ma satysfakcjonuje mnie w pewnym stopniu. Ponadto nie mam zespołu, kontroli i pełną dowolność w pisaniu tego projektu :) więc traktuje go jako pole testowe dla nowych rozwiązań - zupełnie jak bym pisał do szuflady - z tą różnicą, że właścicielka na tym cały czas zarabia i to ładne cyfry, więc i mi coś kapie :)
Pogratulować współpracy :) Wilk syty i owca cała :)
Świetny film :) Zgadzam się w 100% Bardzo pomagają projekty nawet te, które nigdy nie wychodzą spoza prywatnego repozytorium. Pozdrawiam
Adam święta prawda, własny projekt to kopalnia wiedzy i rozwoju 🙂
Super temat, dzięki 😀
🎉🎉🎉
💪💪💪
6:30 Dlaczego tutaj jest oznaczenie OHS przy module "Order"? Nie powinno ono być przy module "Order Return"? Czy może po prostu OHS, czyli moduł wystawiający API, może być zarówno po stronie Upstream jak i Downstream?
Najpierw musimy zdefiniować kto z kim rozmawia, potem co jeden potrzebuje od drugiego, a na końcu w jaki sposób to zaimplementować. OHS jest właśnie tą implementacją. Zwroty potrzebują informacji z Zamówień o tym czy dane zamówienie które klient chce anulować w ogóle istnieje w systemie. OHS jest tutaj właśnie pewnym API, udostępnianym na zewnątrz przez Zamówienia. Czyli to Zamówienia pozwalają innym pytać o dane. Dlatego Zamówienia są niżej, a Zwroty powyżej - bo to Zwroty pytają się Zamówień o dane. Mapa kontekstów z nagrania jest moją interpretacją. Zwroty są wyżej niż Zamówienia ponieważ relacja jest właśnie w tę stronę. Wiele źródeł OHS mówi o tym, że do OHS jest "hostem" lub "suplierem" a wszystko co używa tego OHS jest "comsumerem". Mimo to dla mnie ważna była relacja na diagramie.
@@adambanaszkiewicz Dzięki za wyjaśnienie :)
Pojawiło mi się kolejne pytanie. A co jeśli mamy implementację repo InMemoryProductRepository, a na encji mamy pole $version do optimistic lockingu i dodatkowo w serwisach jawnie korzystamy z transakcji. Czy te dwie rzeczy też muszą być "odpowiednio" obsługiwane przez tą implementację InMemory? Czy wtedy kod tego repozytorium nie będzie zbyt skomplikowany? Jak to wygląda w rzeczywistym projekcie?
Bardzo dobre, nietrywialne pytanie :) Najpierw zadałbym pytanie, czy obsługa optimistic lockingu jest biznesowa czy techniczna. Jeśli techniczna, to nie przejmowałbym się tym w implementacjach InMemory. To mają być proste implementacje, implementujące interfejs. Sam OL można przetestować na co najmniej dwa różne sposoby, i tego bym się trzymał. InMemory bez $version, a integracyjnie przetestować czy dane repo poprawnie obsługuje wersjonowanie. Natomiast gdy OL jest biznesowy, to warto w tedy to bardziej uwydatnić, ale już nie tylko przez $version w encji, ale przez interfejs Repozytorium, rzucane wyjątki, ich obsługę, ewentualnie jeśli potrzeba to nawet nazwy metod. W tedy powinieneś przetestować OL jako część Twojego kontraktu. Tutaj wchodzimy na grząski grunt, nie mając wiedzy biznesowej więc na tym się zatrzymam :D Pytanie ma o wiele więcej niuansów, zakładam, że mogę nie wiedzieć czegoś co mogłoby wpłynąć na moją odpowiedź, więc poproszę byś nie traktował tego jako wyroczni, jeśli popełniłem błąd przez niewiedzę o Twoim przypadku :)
@@adambanaszkiewicz Nie mnie oceniać czy popełniłeś błąd czy nie :D Dzięki! Załapałem Twój sposób myślenia, mam nadzieję :) Biznesowe rzeczy - unitowo i wtedy OL tak; Technicznie - proste testy integracyjne dla OL Czy do transakcji i innych podobnych rzeczy też podchodzimy tak samo? Jeśli w kodzie jest startTransaction(); commit() i rollback()
Transakcje są częścią warstwy Aplikacji (jestem swoją drogą w trakcie pisania tego odcinka :D ). Ta warstwa raczej średnio nadaje się do testowania jednostkowego - bardziej Funkcjonalnie lub nawet Integracyjnie z racji jej przeznaczenia. Testy jednostkowe nie powinny dotykać kodu, który dotyka infrastruktury, a transakcje są właśnie częścią infrastruktury, ale używane są w warstwie Aplikacji bo to ona odpowiada za orkiestrację całego procesu biznesowego i decydowanie co zrobić gdy coś wewnątrz transakcji zawiedzie. Na pewno będę o tym temacie mówił obszernie w odcinku o warstwie Aplikacji. Poproszę o troszkę cierpliwości, i jeśli po obejrzeniu odcinka nadal będziesz miał pytania to w tedy wal śmiało :) Nie chciałbym zwyczajnie pisać tutaj litanii tekstu, skoro o wiele łatwiej i przyjemniej będzie zapoznać się z materiałem video :)
Problemem jest "dodatkowo w serwisach jawnie korzystamy z transakcji". Wycieka wam infra.
@@mleczakm Warstwa aplikacji wie o infrastrukturę. A jeśli potrzebujesz się jej jakkolwiek pozbyć, to możesz spróbować zrobić abstrakcje na transakcję bazodanowa. W jednej z aplikacji tak zrobiliśmy, nazywaliśmy to Operacją Atomową. Pod spodem była zwykła transakcja.
A taka struktura to nie jest Clean Architekture moze? jest jeszcze Hexagonal Architecture ..
Clean i Hexagonal nie narzucają struktury projektu, a tylko reguły którymi mamy podążać w kodzie :) Tak samo DDD i MVC to też reguły. Od każdej reguły można odejść lub ją złamać jeśli jest ku temu racjonalny powód. Ja sugeruję takie a nie inne struktury w filmach, ponieważ z mojej perspektywy są one najpopularniejsze, przy używaniu DDD i MVC, ale nie oznacza to, że są jedyne albo prawidłowe w każdym możliwym przypadku :) Widziałem różne struktury dla DDD, i w większości przypadków po poznaniu powodów dla których podjęta była taka decyzja miało to sens :)
Jestem w zespole SRE ale mam ogólnie interesuje mnie wszystko i tak trafiłem na Twój kontent. Podrzuciłem naszym developerom - nawet nie przyznali że nic z tego nie rozumieją tylko zlali. Jak ten development ma się rozwijać?
Miałem styczność z czymś takim i ciężko to niestety przeskoczyć. Każdy z nas jest inny - jedni chcą się rozwijać i uczyć, innych zadowala to co mają. Jeśli chcesz to napisz do mnie na LinkedIn, podrzucę Ci trochę info jak można spróbować rozruszać zastygłe tryby w firmie :) Pamiętaj, że to tylko sugestie, i nie w każdej sytuacji mogą zadziałać, to zależy od człowieka z którym masz styczność :)
kurde, ja siedze w aplikacji 13sto letniej, napisanej w zend 1 oraz laminas :D i mimo to, że to tak potężne legacy to w każdym module nowy kod wyciągamy jak tylko się da do warstw właśnie :) aplikacja, domena, infra - jedynie kontrolery trzymamy w starym miejscu :) Podział kontextów jest ubogi, bo bazujemy na modułach wydzielonych przez rzeczowniki (czyli moduł = tabelka w bazie :) ) a nie wydzielonych na zachowaniach. No ale tak czy siak, bez bounded contextów nowy kod i ląduje z pdziałem na warstwy, które są pisane w 100% w oderwaniu od frameworka, czyste php :) Da się, tylko trzeba chiceć :)
@@DanielŚmigiela Jak są ludzie którzy chcą coś zmienić to jest więcej niż pół sukcesu :)
Cześć, bardzo fajny temat. Szkoda, że tak rzadko spotykany w firmach ;] Mam tylko jedno ale! Mówisz, że używasz zamiennie słów "bounded context" oraz moduł, i tutaj miałem lekki red alert w głowie, bo zazwyczaj w ramach jednego bounded contextu możemy mieć wszak wiele modułów które rozumieją ten wycinek aplikacji, niejaką granicę lingiwstyczną i odpowiedzialność zmapowanej subdomeny (jeżeli jest 1:1, bo to też nie zawsze). Przykład: Moduły o małej granulacji o nazwie Fast-Checkout oraz Checkout mogą żyć w subdomenie koszyka, moduły o dużej granulacji o nazwie BookReservation oraz BookReturnment mogą żyć w subdomenie jakiegoś działu ksiąg. Wtedy budowanie mapy kontekstów między subdomeną (BC) koszyk a ksiąg (BC) miałoby sens, czy to jakaś forma relacji, czy po prostu seperate ways by podkreślić że nie mogą se sobą te dwa bounded konteksty rozmawiać i jest to zabieg celowy
Masz rację 😎 Używałem tego zamiennie w celach czysto skrótowych, by nie wydłużać filmu, by nie wchodzić w rozważania czym jest BC a czym moduł, bo film musiałby być dwa razy dłuższy 😄
Fajny materiał 👍 Mam wrażenie, że jest tutaj jednak pewna nieścisłość. Controller odbierający żądania http powinien wg mnie być w warstwie infrastruktury i nie wywoływać akcji bezpośrednio na obiektach domenowych tylko delegować akcje do serwisu aplikacyjnego (use case) znajdującego się w warstwie aplikacji. W serwisie aplikacyjnym właśnie powinien być kod odpowiedzialny za sklejenie procesu czyli pobranie obiektow z bazy, wykonanie na nich akcji, zapisanie do bazy itp. To powoduje, że jeśli obok żądań http będziemy tworzyć zamówienie w reakcji na np. event z kolejki lub inny endpoint to nie będziemy powtarzać tych samych akcji w każdym z tych miejsc. W każdym razie - samo przedstawienie idei odwrócenia zależności i czystej domeny - super 👍
Mass rację, tak to powinno wyglądać :) Będę o tym opowiadał w kolejnych częściach dotyczących właśnie warstw Aplikacji i UserInterface/Presentation. Skupiam się po kolei na każdej z warstw, żeby film był kompletny ale nie zbyt obszerny.
@@adambanaszkiewicz ok 👍 w takim razie wybiegłem trochę wprzód 😄 Powodzenia w tworzeniu kanału! 👍
Keep up the good job!
T. Hanks :)
Jeden z lepszych filmów o programowaniu jakie widziałem :)
Czuję się zaszczycony :) Postaram się by jakość pozostała na tym samym poziomie w kolejnych częściach :)
Przydał by się link do repo jak było przed jak jest po łatwiej się czyta, pozostawienie nazwy DownloadManager to zaproszenie do złamania SRP w przyszłości
Ah, z tą nazwą to masz racje. Nie pomyślałem by ją zmienić. Za bardzo skupiłem się na wydzieleniu odpowiedzialności :)
Możesz lookać :) github.com/adambanaszkiewicz/four-layers-of-application-example
Absolutnie zgadzam się z idea redukcji mocków, które konczy sie najczęściej testami implementacji, a nie zachowania. Zastanawia mnie jednak czemu nie rozwinąleś mocniej tematu innych typów test doubles, ktorymi mozna osiagnac podobny cel, czyli stubami? Czy są argumenty, które powodują, że moga one nie spełniać Twoich wymagań co do testowania wyłącznie zachowania?
Mam w planach odcinek poświęcony wszystkim rodzajom dublerów testowych :) Tutaj chciałem się skupić tylko na problemie mocków i jak je zastąpić :)
dobre to, ku.wa! 😉
Jest szmoc!
Wszystko spoko, ale mam jedno pytanie, bo w oryginalnym teście było testowane czy plik istnieje na serwerze. Nie było tam żadnej logiki - co jeśli istnieje a co jeśli nie. Była tam też jakaś logika expire date cos tam < now(). W nowej wersji zabrakło tej logiki. No i mamy problem bo testy cyk na zielono a produkcja nie działa. Czy w takim teście "DownloadManager" nie powinna być testowana własnie ta logika? No chyba ze fider ma tego ifa od `expire date` w sobie, ale to znowu ogranicza metodę bo będzie zwracać tylko takie co maja dobra datę, a może ktoś by chciał te inne też. Czy nie lepiej by było DownloadMenegerowi przekazac te dwa miedzymordzia :D , albo chociaż FileSystemInterface, a sam obiekt file dac jako paramter do metody fileExistOnServer? P.S używanie now() w logice biznesowej uważam za nie stosowne :D ile już testów się napoprawiałem bo rok przestępny i data się nie zgadza :D
Bardzo dobre spostrzeżenia waćpan masz :) Celem było pokazanie problemów z Mockami, cała metoda i test był dla zobrazowania problemu pokazany. Faktycznie, to też powinno być zrefaktoryzowane, natomiast traktuj ten przykład jak taki jeden z wielu, który masz w kodzie legacy, który ma problemy nie tylko w Mockach ale też właśnie w tych miejscach o których wspominasz. Mam w planach zrobić odcinek właśnie o tym używaniu now() i paru innych rzeczach w testach, które jebitnie je rozpierdalają, ale na pierwszy rzut oka :D
A jak wygląda testowanie połączenia "klasa - klasa"? Integracyjnie bez mocków?
Tylko co chcesz tak przetestować? Powinniśmy testować zachowanie. Jeśli częścią zachowania jest odpytanie innej klasy to ta "inna" klasa powinna być używana bezpośrednio jako zależność, nie jako Mock/Spy/Fake. Jeśli podrzucisz więcej info to będę mógł odpowiedzieć bardziej konkretnie :)
@@adambanaszkiewicz Niech będzie, że jest zachowanie "wygenerujToken", który korzysta z trzech innych klas. Nie dotykają żadnego API, żadnej bazy danych, nic z zewnątrz. W sumie załóżmy, że tylko do frameworka Symfony mają zależności. W takiej sytuacji najlepszym pomysłem integracyjnie to przetestować i bez żadnych mocków i dublerów? Czy gdyby nie było zależności do frameworka to wtedy można by jednostkowo to przetestować budując graf obiektów i też bez korzystania z mocków?
Test integracyjny to test który wychodzi poza proces, czyli idzie do bazy, do systemu plików, do jakiegoś API zewnętrznego. Jeśli Twoja klasa używa Symfony, ale te klasy SYmfony nie wychodzą "na zewnątrz" to nadal to jest test jednostkowy :) A odpowiadając na Twoje pytanie, "wygenerujToken" jest Twoim zachowaniem, zakładam, że zwraca ten token i jego testujesz. W tedy w teście jednostkowym musisz stworzyć obiekt klasy, którą testujesz, plus wszystkie zależności tej klasy, niezbędne do wykonania tego zachowania (zakładając, że to nie jest test integracyjny jak opisałem wyżej). Nawet mając zależność do frameworka, powinieneś zbudować pełny graf obiektów, zależności, który jest potrzebny by wygenerować ten token. Oczywiście nadal mając na uwadze, że te zależności operują nadal w tym procesie, i nie "wychodzą na zewnątrz", jak opisałem w pierwszym akapicie. Mam nadzieję, że w miarę jasno opisałem, ale jak masz jeszcze pytania to wal, chętne podyskutuję :)
@@adambanaszkiewicz Czy test jednostkowy to będzie zawsze dziedziczył po TestCase? Czy po KernelTestCase też może? Czy w teście jednostkowym taki graf obiektów można sobie wyciągnąć z kontenera zależności czy musimy go budować ręcznie? W sumie zawsze rozróżniałem testy jednostkowe i integracyjne według tego czy dany test dziedziczy po TestCase (unitowy) czy KernelTestCase (integracyjny). Czy taki sposób myślenia jest poprawny?
Tak, taki sposób myślenia jest ok. WebTestCase/KernelTestCase uruchamia cały kernel, więc niejako od razu masz dostęp do bazy danych itp. Nie musisz oczywiście z tego korzystać, ale już sam fakt zbudowania całego kernela i kontenera DI świadczy o tym, że to test integracyjny. Test jednostkowy ma za zadanie przetestowanie tylko jednego zachowania, i do tego mamy TestCase. Co do grafu obiektów z kontenera DI - jeśli masz kontener to to nie jest test jednostkowy. Graf obiektów, które są wymagane do przetestowania danego zachowania, MUSI być stworzony ręcznie w teście. Albo przez jakiś pattern typu Fabryka lub ObjectMother, jeśli wygodniej. Natomiast samo użycie DI automatycznie przenosi test na półkę testy integracyjnego.
Powodzenia w rozwijaniu kanału! Im więcej dobrej treści tym lepiej 🔥🔥🔥
A dziękuję, dziękuję :)
Oooo PHP :D
Skont wiesz?! :D
@@adambanaszkiewicz Po deptracu, ale w moim serduszku też gości PHP i za to poleciała łapka w górę :D
@@kosaa03 Dzięki :)