{"id":29370,"date":"2019-09-24T05:47:27","date_gmt":"2019-09-24T03:47:27","guid":{"rendered":"https:\/\/nearshore-it.eu\/artykuly\/porty-i-adaptery-w-praktyce\/"},"modified":"2024-11-07T15:00:32","modified_gmt":"2024-11-07T14:00:32","slug":"porty-i-adaptery-w-praktyce","status":"publish","type":"post","link":"https:\/\/nearshore-it.eu\/pl\/artykuly\/porty-i-adaptery-w-praktyce\/","title":{"rendered":"Porty i adaptery w praktyce"},"content":{"rendered":"\n<div class=\"table-of-contents\">\n    <p class=\"title\">Id\u017a do:<\/p>\n    <ol>\n                    <li><a href=\"#Architektura-wzorca-porty-i-adaptery\">1.  Architektura wzorca porty i adaptery<\/a><\/li>\n                    <li><a href=\"#Porty-i-adaptery-przyk\u0142adowa-implementacja\">2.  Porty i adaptery \u2013 przyk\u0142adowa implementacja<\/a><\/li>\n                    <li><a href=\"#Architektura-hexagonalna-organizacja-i-opis-pakiet\u00f3w\">3.  Architektura hexagonalna \u2013 organizacja i opis pakiet\u00f3w<\/a><\/li>\n                    <li><a href=\"#Architektura-hexagonalna-opis-implementacji-klas\">4.  Architektura hexagonalna \u2013 opis implementacji klas<\/a><\/li>\n                    <li><a href=\"#Porty-i-adaptery-najcz\u0119stsze-pytania\">5.  Porty i adaptery \u2013 najcz\u0119stsze pytania<\/a><\/li>\n                    <li><a href=\"#Podsumowanie\">6.  Podsumowanie<\/a><\/li>\n            <\/ol>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\" id=\"Architektura-wzorca-porty-i-adaptery\">Architektura wzorca porty i adaptery<\/h2>\n\n\n\n<p>Wzorzec <strong>porty i adaptery (ang. ports &amp; adapters) <\/strong>okre\u015blany r\u00f3wnie\u017c jako architektura hexagonalna (ang. <strong>hexagonal architecture) <\/strong>to nic innego jak wzorzec narzucaj\u0105cy spos\u00f3b budowy i organizacji kodu aplikacji. G\u0142\u00f3wnym za\u0142o\u017ceniem tego wzorca jest tworzenie kodu w taki spos\u00f3b, aby maksymalnie odseparowa\u0107 implementacj\u0119 logiki biznesowej od wszelkich zale\u017cno\u015bci zewn\u0119trznych, takich jak frameworki, bazy danych, us\u0142ugi zewn\u0119trzne itp. Dzi\u0119ki temu zyskujemy wi\u0119ksz\u0105 kontrol\u0119 nad kodem i niezale\u017cno\u015b\u0107 od zewn\u0119trznych bibliotek oraz wprowadzanych w nich zmian.&nbsp;Przyjrzyjmy si\u0119 bli\u017cej wzorcowi:<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/nearshore-it.eu\/wp-content\/uploads\/2024\/09\/jpro_graphic_ports_adapters.png\" alt=\"Porty i adaptery\" class=\"wp-image-24109\" title=\"\"><\/figure>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p><strong>Wzorzec port\u00f3w i adapter\u00f3w dzieli struktur\u0119 kodu na dwa obszary:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>wewn\u0119trzny (application \/ domain)<\/li>\n\n\n\n<li>zewn\u0119trzny (infrastructure)<\/li>\n<\/ul>\n\n\n\n<p>Obszar wewn\u0119trzny skupia si\u0119 na rozwi\u0105zaniu i implementacji g\u0142\u00f3wnego problemu (use case). Obszar ten nie ma \u017cadnych odniesie\u0144 do framework\u00f3w, baz danych i innych us\u0142ug lub bibliotek zewn\u0119trznych, ani nie czerpie z nich. Obszar zewn\u0119trzny z kolei zawiera implementacj\u0119 port\u00f3w w postaci adapter\u00f3w oraz klasy zwi\u0105zane z frameworkami, jak na przyk\u0142ad Spring, Hibernate itp. Komunikacja pomi\u0119dzy obszarem wewn\u0119trznym i zewn\u0119trznym realizowana jest za pomoc\u0105 port\u00f3w i ich implementacji, czyli adapter\u00f3w (st\u0105d te\u017c nazwa wzorca).<\/p>\n\n\n\n<p>Kilka podstawowych za\u0142o\u017ce\u0144 architektury typu porty i adaptery:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Obszar wewn\u0119trzny, czyli w\u0142a\u015bciwa implementacja logiki, \u201enic nie wie\u201d o obszarze zewn\u0119trznym. Nie ma zale\u017cno\u015bci pomi\u0119dzy tym obszarem a frameworkami (jak wspomniane Spring, Hibernate itp.).<\/li>\n\n\n\n<li>Logika rozwi\u0105zania problemu zamkni\u0119ta jest w obszarze wewn\u0119trznym. Dost\u0119p do niej mamy wy\u0142\u0105cznie za po\u015brednictwem klasy fasady domenowej, o kt\u00f3rej pisz\u0119 wi\u0119cej w dalszej cz\u0119\u015bci artyku\u0142u.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"Porty-i-adaptery-przyk\u0142adowa-implementacja\">Porty i adaptery \u2013 przyk\u0142adowa implementacja<\/h2>\n\n\n\n<p>G\u0142\u00f3wnym celem przyk\u0142adu jest zaprezentowanie implementacji klas i organizacja pakiet\u00f3w w oparciu o idee architektury typu ports &amp; adapters. Za przyk\u0142ad niech pos\u0142u\u017cy obszar domeny odpowiedzialny za rejestracj\u0119 nowych u\u017cytkownik\u00f3w w systemie. Zaimplementowane zosta\u0142y tutaj dwa przypadki u\u017cycia:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>rejestracja nowego u\u017cytkownika \u2013 obejmuje funkcjonalno\u015bci zwi\u0105zane z wygenerowaniem kodu aktywacji konta oraz wys\u0142anie maila aktywacyjnego.<\/li>\n\n\n\n<li>aktywacja konta u\u017cytkownika \u2013 weryfikuje wygenerowany kod i aktywuje konto oraz wysy\u0142a komunikat do systemu zewn\u0119trznego.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"Architektura-hexagonalna-organizacja-i-opis-pakiet\u00f3w\">Architektura hexagonalna \u2013 organizacja i opis pakiet\u00f3w<\/h2>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/nearshore-it.eu\/wp-content\/uploads\/2024\/09\/jpro_graphic_2_ports_adapters.png\" alt=\"Porty i adaptery \" class=\"wp-image-24110\" title=\"\"><\/figure>\n<\/div>\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Pakiet: <strong>user<\/strong><\/li>\n<\/ol>\n\n\n\n<p>To g\u0142\u00f3wny pakiet domeny, w obr\u0119bie kt\u00f3rej b\u0119dziemy si\u0119 poruszali. Czyli domeny u\u017cytkownik\u00f3w. Pakiet ten zawiera dwa podpakiety: <strong>crud <\/strong>oraz <strong>registration&nbsp;<\/strong><\/p>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>Pakiet: <strong>user.crud&nbsp;<\/strong><\/li>\n<\/ol>\n\n\n\n<p>W pakiecie tym zosta\u0142a zamkni\u0119ta logika zwi\u0105zana z prostymi operacjami pobierania danych. Ponadto mo\u017ce on zawiera\u0107 inne operacje, kt\u00f3re nie posiadaj\u0105 z\u0142o\u017conej logiki biznesowej i s\u0142u\u017c\u0105 wy\u0142\u0105cznie prostym operacjom typu CRUD (od: <strong><em>c<\/em><\/strong><em>reate,&nbsp;<strong>r<\/strong>ead,&nbsp;<strong>u<\/strong>pdate and&nbsp;<strong>d<\/strong>elete)<\/em>.<\/p>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li>Pakiet: <strong>user.registration&nbsp;<\/strong><\/li>\n<\/ol>\n\n\n\n<p>Ten pakiet zawiera wszystkie klasy zwi\u0105zane z logik\u0105 rejestracji nowych u\u017cytkownik\u00f3w w aplikacji (implementacja i obs\u0142uga wspomnianych wcze\u015bniej przypadk\u00f3w u\u017cycia).<\/p>\n\n\n\n<ol start=\"4\" class=\"wp-block-list\">\n<li>Pakiet: <strong>user.registration.domain<\/strong><\/li>\n<\/ol>\n\n\n\n<p>Pakiet zawiera klasy z g\u0142\u00f3wn\u0105 implementacj\u0119 logiki biznesowej oraz definicje <strong>port\u00f3w<\/strong> (interfejsy Java), za po\u015brednictwem kt\u00f3rych odbywa si\u0119 komunikacja z innymi komponentami systemu. Pakiet <strong>core.user.registration.domain<\/strong> zawiera kod vanilla Java, tzn. kod, kt\u00f3ry nie jest zale\u017cny od framework\u00f3w i innych bibliotek zewn\u0119trznych.&nbsp;Jedynym punktem dost\u0119pu do zaimplementowanej logiki w tym pakiecie jest klasa fasady. Co wa\u017cne: to, jakich bibliotek b\u0119dziemy u\u017cywali (np.: commons-lang, Dozer, Orika) wewn\u0105trz pakietu, zale\u017cy od zespo\u0142u i og\u00f3lnych ustale\u0144 w projekcie.<\/p>\n\n\n\n<ol start=\"5\" class=\"wp-block-list\">\n<li>Pakiet: <strong>user.registration.infrastructure<\/strong><\/li>\n<\/ol>\n\n\n\n<p>Pakiet ten zawiera implementacj\u0119 <strong>adapter\u00f3w<\/strong>, kt\u00f3re wykorzystywane s\u0105 za po\u015brednictwem zdefiniowanych w kodzie domeny port\u00f3w. W pakiecie zamkni\u0119ta jest implementacja i konfiguracja komponent\u00f3w korzystaj\u0105cych z funkcji i metod framework\u00f3w. Cz\u0119sto u\u017cywane s\u0105 tutaj biblioteki innych dostawc\u00f3w rozwi\u0105za\u0144, kt\u00f3re s\u0105 odpowiedzialne np. za generowanie plik\u00f3w PDF, wysy\u0142anie maili czy komunikacj\u0119 z systemami zewn\u0119trznymi, takimi jak Kafka, SOAP itp.<\/p>\n\n\n\n<ol start=\"6\" class=\"wp-block-list\">\n<li>Pakiet: <strong>user.registration.infrastructure.config<\/strong><\/li>\n<\/ol>\n\n\n\n<p>W pakiecie tym powinna znale\u017a\u0107 si\u0119 konfiguracja zwi\u0105zana z tworzeniem i obs\u0142ug\u0105 komponent\u00f3w wykorzystywanego frameworka.<\/p>\n\n\n\n<ol start=\"7\" class=\"wp-block-list\">\n<li>Pakiet: <strong>user.registration.infrastructure.entrypoint<\/strong><\/li>\n<\/ol>\n\n\n\n<p>Pakiet ten zawiera klasy kontroler\u00f3w i klasy typu DTO, za po\u015brednictwem kt\u00f3rych inne systemy czy modu\u0142y mog\u0105 korzysta\u0107 z funkcji naszej domeny. Klasy DTO opisuj\u0105 struktury danych wej\u015bciowych i wyj\u015bciowych dla REST API.<strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/strong><\/p>\n\n\n\n<ol start=\"8\" class=\"wp-block-list\">\n<li>Pakiet: <strong>user.registration.infrastructure.repository<\/strong><\/li>\n<\/ol>\n\n\n\n<p>Pakiet klas zwi\u0105zanych z warstw\u0105 persystencji,&nbsp;czyli klasy odpowiedzialne za pobieranie i zapisywanie danych w bazie. S\u0105 to definicje modelu danych (ORM), klasy DAO. Pakiet ten zawiera m.in. implementacj\u0119 klasy adaptera dost\u0119pu do danych. W bardziej rozbudowanych przypadkach mo\u017cemy mie\u0107 wi\u0119cej klas modelu lub odwo\u0142ywa\u0107 si\u0119 do klas modelu (ORM) z innych pakiet\u00f3w.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"Architektura-hexagonalna-opis-implementacji-klas\">Architektura hexagonalna \u2013 opis implementacji klas<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Klasy z pakietu <strong>user.registration.domain<\/strong>:<\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>UserRegistration <\/strong>\u2013 g\u0142\u00f3wna klasa implementacji logiki biznesowej. Dost\u0119p do klasy ograniczony na poziomie pakietu.<\/li>\n\n\n\n<li><strong>UserRegistrationDataProvider <\/strong>\u2013 port dla operacji wej\u015bcia \/ wyj\u015bcia (we\/wy) zwi\u0105zanych z dost\u0119pem do bazy danych,<\/li>\n\n\n\n<li><strong>UserRegistrationNotifier <\/strong>\u2013 port wyj\u015bciowy do wysy\u0142ania komunikat\u00f3w na kolejk\u0119,<\/li>\n\n\n\n<li><strong>ConfirmationMailSender <\/strong>\u2013 port wyj\u015bciowy do wysy\u0142ania wiadomo\u015bci mailem.<\/li>\n<\/ul>\n\n\n\n<p>Wy\u017cej wymienione porty to publiczne interfejsy klas Java, kt\u00f3rych implementacja odbywa si\u0119 na poziomie pakiet\u00f3w infrastruktury.<\/p>\n\n\n\n<p><strong>UserRegistrationFacade <\/strong>\u2013 fasada domeny. Klasa, za po\u015brednictwem kt\u00f3rej mamy dost\u0119p do metod (funkcji) domeny. W przedstawionym przyk\u0142adzie klasa fasady pe\u0142ni funkcj\u0119 wywo\u0142uj\u0105c\u0105 dla klasy <strong>UserRegistration, <\/strong>czyli pe\u0142ni dla niej funkcj\u0119 wrappera. W bardziej z\u0142o\u017conych przypadkach mo\u017cemy posiada\u0107 wi\u0119cej klas zawieraj\u0105cych logik\u0119 biznesow\u0105. W\u00f3wczas fasada stanowi punkt dost\u0119pu do wywo\u0142a\u0144 wszystkich tych funkcji domeny. Czasami mo\u017ce si\u0119 zdarzy\u0107, \u017ce b\u0119dziemy potrzebowali do\u0142o\u017cy\u0107 na tym etapie okre\u015blone walidacje zwi\u0105zane z frameworkami. Mo\u017ce by\u0107 to podyktowane tym, \u017ce niekt\u00f3re inne obszary domenowe b\u0119d\u0105 potrzebowa\u0142y wykorzysta\u0107 logik\u0119 z innej domeny. Mo\u017cna w\u00f3wczas na poziomie fasady korzysta\u0107 z funkcji walidacji. Oczywi\u015bcie wszystko podobnie jak we wspomnianych wcze\u015bniej przypadkach zale\u017cy od og\u00f3lnych ustale\u0144 i za\u0142o\u017ce\u0144 projektowych w zespole.<\/p>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>Klasy z pakietu <strong>user.registration.infrastructure<\/strong><\/li>\n<\/ol>\n\n\n\n<p>Implementacja adapter\u00f3w:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>ConfirmationMailSenderAdapter<\/strong><\/li>\n\n\n\n<li><strong>UserRegistrationNotifierAdapter<\/strong><\/li>\n\n\n\n<li><strong>UserRegistrationDataProviderAdapter<\/strong><\/li>\n<\/ul>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li>Klasa <strong>UserRegistrationService <\/strong>jest odpowiedzialna za transakcyjno\u015b\u0107 wykonywanych operacji. Klasa ta za po\u015brednictwem klasy fasady <strong>UserRegistrationFacade<\/strong> wywo\u0142uje kod logiki biznesowej.&nbsp;W przypadku bardziej z\u0142o\u017conych operacji na poziomie tej klasy mog\u0105 by\u0107 wstrzykiwane fasady pochodz\u0105ce z innych obszar\u00f3w.<\/li>\n\n\n\n<li>Klasy z pakietu <strong>user.registration.entrypoint.<\/strong><\/li>\n\n\n\n<li>Klasa kontrolera <strong>UserRegistrationController <\/strong>wystawia REST API. U\u017cywa klasy <strong>UserRegistrationService&nbsp;realizuj\u0105cej<\/strong> operacje wymagaj\u0105ce. transakcji. W przypadku gdy operacje nie wymagaj\u0105 od nas transakcji, mo\u017cemy w klasie tej bezpo\u015brednio korzysta\u0107 z klasy fasady.<\/li>\n<\/ol>\n\n\n\n<p>W przyk\u0142adowej implementacji pakietu domain wida\u0107 du\u017c\u0105 liczb\u0119 klas \u2013 jest to jeden z atrybut\u00f3w tego wzorca. Dzi\u0119ki temu uzyskujemy hermetyczno\u015b\u0107 implementacji logiki biznesowej i struktur z ni\u0105 zwi\u0105zanych. Punktem dost\u0119pu do funkcji domeny jest klasa fasady. Z za\u0142o\u017cenia klasy pakietu domain nie powinny u\u017cywa\u0107 klas framework\u00f3w, st\u0105d te\u017c wi\u0119ksza liczba klas POJO (plain old Java object) zwi\u0105zanych z danymi. W wypadku z\u0142o\u017conych przypadk\u00f3w u\u017cycia mo\u017cna tworzy\u0107 wi\u0119ksz\u0105 liczb\u0119 klas z implementacj\u0105 logiki biznesowej. W przyk\u0142adzie mo\u017cna np. wydzieli\u0107 aktywacj\u0119 konta do osobnej klasy.<\/p>\n\n\n\n<p><strong>Przeczytaj tak\u017ce: <a href=\"https:\/\/nearshore-it.eu\/pl\/artykuly\/test-driven-development-na-co-dzien\">Test-Driven Development na co dzie\u0144<\/a><\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"Porty-i-adaptery-najcz\u0119stsze-pytania\">Porty i adaptery \u2013 najcz\u0119stsze pytania<\/h2>\n\n\n\n<p><strong>Dlaczego musimy ogranicza\u0107 dost\u0119p do niekt\u00f3rych klas na poziomie pakietu?<\/strong><\/p>\n\n\n\n<p>Za pomoc\u0105 modyfikator\u00f3w dost\u0119pu do klas i metod ukrywamy szczeg\u00f3\u0142y implementacji \u2013 czyli stosujemy tzw. hermetyzacj\u0119 klas. Zapewniamy tym samym kontrol\u0119 nad dost\u0119pem, stanem i zachowaniem obiektu. &nbsp;W naszym przyk\u0142adzie w pakiecie domain dost\u0119p publiczny posiadaj\u0105: klasa fasady oraz klasy reprezentuj\u0105ce dane wej\u015bciowe i wyj\u015bciowe. Ca\u0142a implementacja logiki jest zamkni\u0119ta na poziomie pakietu i dost\u0119p do operacji jest mo\u017cliwy wy\u0142\u0105cznie za po\u015brednictwem metod zdefiniowanych w klasie fasady.<\/p>\n\n\n\n<p><strong>Co z bibliotekami typu Lombok, JSR 303 (walidacja) lub loggerami w pakiecie domain?<\/strong><\/p>\n\n\n\n<p>Zgodnie z g\u0142\u00f3wn\u0105 ide\u0105 architektury hexagonalnej nie powinni\u015bmy u\u017cywa\u0107 bibliotek zewn\u0119trznych. Praktyka dowodzi jednak czego\u015b innego. To, jakich bibliotek u\u017cyjemy wewn\u0105trz domeny, zale\u017cy od decyzji zespo\u0142u, gdy\u017c ka\u017cda osoba w zespole ma inne do\u015bwiadczenia i pomys\u0142y. Warto jednak zastosowa\u0107 pewne ograniczenia co do tych narz\u0119dzi. W projektach, w kt\u00f3rych bra\u0142em udzia\u0142, ograniczali\u015bmy si\u0119 g\u0142\u00f3wnie do bibliotek typu java commons, biblioteki mapper\u00f3w oraz walidacji.<\/p>\n\n\n\n<p><strong>Porty i adaptery \u2013 gdzie zak\u0142ada\u0107 transakcje?<\/strong><\/p>\n\n\n\n<p>Jednym z wa\u017cniejszych element\u00f3w implementacji operacji jest ich transakcyjno\u015b\u0107.<br>Cz\u0119sto wymagana operacja b\u0119dzie potrzebowa\u0142a wykorzysta\u0107 funkcj\u0119 z innej domeny kodu lub b\u0119dziemy chcieli wywo\u0142a\u0107 funkcj\u0119 domeny w transakcji. W\u00f3wczas musimy zapewni\u0107 transakcyjno\u015b\u0107 dla wywo\u0142a\u0144 tych funkcji. Dla takiego przypadku mo\u017cna zbudowa\u0107 dedykowany serwis, kt\u00f3ry b\u0119dzie zawiera\u0142 klasy fasad domenowych.<br>W przyk\u0142adzie serwis zosta\u0142 zaimplementowany w klasie <strong>UserRegistrationService.<\/strong><\/p>\n\n\n\n<p><strong>Dlaczego nie powinni\u015bmy zak\u0142ada\u0107 transakcji w klasie fasady?<\/strong><\/p>\n\n\n\n<p>Brak transakcji w klasie fasady wynika z za\u0142o\u017cenia, \u017ce kod w pakiecie domain ma by\u0107 wolny od wszelkich framework\u00f3w.<\/p>\n\n\n\n<p><strong>Czy mo\u017cna u\u017cywa\u0107 DDD razem ze wzorcem ports &amp; adapters?<\/strong><\/p>\n\n\n\n<p>DDD (Domain-Driven Design) skupia si\u0119 na domenie i zawartej w niej logice biznesowej. Nie ma nic wsp\u00f3lnego z frameworkami i transakcjami. W przyk\u0142adzie cz\u0119\u015b\u0107 zwi\u0105zana z DDD zosta\u0142a zaimplementowana w pakiecie domain. Wzorzec ports &amp; adapters pomaga nam uporz\u0105dkowa\u0107 kod i odseparowa\u0107 dost\u0119p do zaimplementowanej logiki. Mo\u017cna stwierdzi\u0107, \u017ce wzorzec ten bardziej odpowiada za warstw\u0119 aplikacyjn\u0105 rozwi\u0105zania, poniewa\u017c odpowiada m.in. za dostarczenie mechanizm\u00f3w konfiguracji, transakcji czy persystencji. Podej\u015bcie DDD oraz wzorzec ports &amp; adapters wsp\u00f3\u0142graj\u0105 ze sob\u0105 w strukturach kodu. DDD rozwi\u0105zuje problem logiczny, a P&amp;A zapewnia dost\u0119p do technicznych mechanizm\u00f3w i bibliotek.<\/p>\n\n\n\n<p><strong>Czy zawsze powinni\u015bmy stosowa\u0107 wzorzec ports &amp; adapters?<\/strong><\/p>\n\n\n\n<p>Je\u017celi zastanawiamy si\u0119, kiedy stosowa\u0107 architektur\u0119 hexagonaln\u0105, decyduj\u0105cy b\u0119dzie aspekt logiki biznesowej. Wzorzec ports &amp; adapters idealnie sprawdzi si\u0119 w przypadku rozbudowanej logiki biznesowej, gdy chcemy skupi\u0107 si\u0119 na rozwi\u0105zaniu problem\u00f3w, kt\u00f3re zosta\u0142y tam postawione. Kod jest wolny od wszelkich framework\u00f3w, dzi\u0119ki czemu \u0142atwo si\u0119 nim zarz\u0105dza i testuje. jest to, \u017ce testy uruchamia si\u0119 szybko i pisze \u0142atwo. Piszemy mniej test\u00f3w integracyjnych \u2013 du\u017c\u0105 cz\u0119\u015b\u0107 logiki pokrywaj\u0105 testy jednostkowe. W testach integracyjnych weryfikujemy krytyczne \u015bcie\u017cki.<\/p>\n\n\n\n<p>Podej\u015bcie to narzuca nam tworzenie wi\u0119kszej liczby klas w celu odseparowania si\u0119 od reszty kodu spoza pakietu, co na pierwszy rzut oka wydaje si\u0119 nadmiarowe. Dzi\u0119ki temu jednak \u0142atwiej jest wydzieli\u0107 logik\u0119 do osobnych niezale\u017cnych modu\u0142\u00f3w (w architekturach mikroserwisowych cz\u0119sto pojawia si\u0119 potrzeba wydzielenia logiki do osobnej us\u0142ugi).<\/p>\n\n\n\n<p>W przypadku aplikacji, kt\u00f3re posiadaj\u0105 ma\u0142o logiki biznesowej lub wr\u0119cz jej nie ma (aplikacje typu CRUD), lepszym podej\u015bciem jest budowa struktury kodu w formie wielowarstwowej (Controller \u2013 Service \u2013 Repository). W przyk\u0142adzie zosta\u0142 wydzielony pakiet CRUD, w kt\u00f3rym zaimplementowana zosta\u0142a prosta operacja pobrania listy u\u017cytkownik\u00f3w.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"Podsumowanie\">Podsumowanie<\/h2>\n\n\n\n<p>Mam nadziej\u0119, \u017ce uda\u0142o mi si\u0119 przedstawi\u0107 g\u0142\u00f3wne idee budowy kodu w architekturze port\u00f3w i adapter\u00f3w oraz odpowiedzie\u0107 na cz\u0119\u015b\u0107 pyta\u0144, kt\u00f3re mog\u0105 pojawi\u0107 si\u0119 podczas implementacji. Oczywi\u015bcie w ka\u017cdym projekcie mo\u017ce wygl\u0105da\u0107 to inaczej. Wszystko zale\u017cy od Was. To zesp\u00f3\u0142 tworzy oprogramowanie \u2013 organizacja i struktura kodu powinna by\u0107 czytelna dla wszystkich i umo\u017cliwia\u0107 wygodn\u0105 prac\u0119. Tak naprawd\u0119 to, jak zaimplementowany zostanie wzorzec, zale\u017cy wi\u0119c od zespo\u0142u i jego decyzji.<\/p>\n\n\n\n<p><strong>Zobacz wi\u0119cej: <\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><a href=\"https:\/\/github.com\/pwitkowsdev\/jc-ports-and-adapters\" target=\"_blank\" rel=\"noopener\">przyk\u0142adowa implementacja aplikacji<\/a><\/strong><\/li>\n\n\n\n<li><strong><a href=\"https:\/\/nearshore-it.eu\/pl\/artykuly\/clean-architecture\">Clean architecture<\/a><\/strong><\/li>\n<\/ul>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Podczas tworzenia system\u00f3w informatycznych pojawiaj\u0105 si\u0119 pytania dotycz\u0105ce wyboru architektury i organizacji kodu. W dzisiejszym artykule chcia\u0142bym bli\u017cej przedstawi\u0107 architektur\u0119 port\u00f3w i adapter\u00f3w (ports &#038; adapters) w praktyce oraz rozwia\u0107 wszelkie w\u0105tpliwo\u015bci zwi\u0105zane z tym wzorcem. Jakie s\u0105 najwi\u0119ksze zalety architektury tupu porty i adaptery? Czy sprawdzi si\u0119 ona w ka\u017cdym przypadku?<\/p>\n","protected":false},"author":117,"featured_media":29378,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"iawp_total_views":1079,"footnotes":""},"categories":[1,582],"tags":[568],"offering":[513],"class_list":["post-29370","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-artykuly","category-technologie","tag-java-pl","offering-application-development"],"acf":[],"_links":{"self":[{"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/posts\/29370","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/users\/117"}],"replies":[{"embeddable":true,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/comments?post=29370"}],"version-history":[{"count":3,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/posts\/29370\/revisions"}],"predecessor-version":[{"id":33919,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/posts\/29370\/revisions\/33919"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/media\/29378"}],"wp:attachment":[{"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/media?parent=29370"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/categories?post=29370"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/tags?post=29370"},{"taxonomy":"offering","embeddable":true,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/offering?post=29370"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}