{"id":2446,"date":"2023-02-01T08:36:35","date_gmt":"2023-02-01T08:36:35","guid":{"rendered":"https:\/\/www.juniorjavadeveloper.pl\/?p=2446"},"modified":"2023-11-21T17:53:00","modified_gmt":"2023-11-21T17:53:00","slug":"od-czego-zaczac-tworzenie-aplikacji-przestan-pisac-kod-zrodlowy-praktyczny-przyklad","status":"publish","type":"post","link":"https:\/\/www.juniorjavadeveloper.pl\/en\/2023\/02\/01\/od-czego-zaczac-tworzenie-aplikacji-przestan-pisac-kod-zrodlowy-praktyczny-przyklad\/","title":{"rendered":"Od czego zacz\u0105\u0107 tworzenie aplikacji? &#8211; Przesta\u0144 pisa\u0107 kod \u017ar\u00f3d\u0142owy &#8211; praktyczny przyk\u0142ad"},"content":{"rendered":"<p class=\"wp-block-paragraph\">Tym razem artyku\u0142 rozpoczn\u0119 praktycznym przyk\u0142adem, kt\u00f3ry zobrazuje moje podej\u015bcie, od kt\u00f3rego zaczynam tworzenia aplikacji. Chc\u0119 pokaza\u0107 jak &#8220;proste&#8221; i skuteczne jest, to podej\u015bcie. Nast\u0119pnie, w dalszej cz\u0119\u015bci opisz\u0119, co, jak i dlaczego zrobi\u0142em.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Wyobra\u017amy sobie, \u017ce zosta\u0142em poproszony o napisanie <strong>wersji demonstracyjnej<\/strong>, tzw. <a href=\"https:\/\/en.wikipedia.org\/wiki\/Proof_of_concept\" data-type=\"URL\" data-id=\"https:\/\/en.wikipedia.org\/wiki\/Proof_of_concept\" target=\"_blank\" rel=\"noreferrer noopener\">Proof of Concept<\/a> <strong>aplikacji bankowej<\/strong>. Od czego zacz\u0105\u0107? Nie wpada\u0107 w panik\u0119! Opisz\u0119 s\u0142ownie, w du\u017cym uproszczeniu, co wed\u0142ug mnie powinna robi\u0107 aplikacja bankowa.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Opis w formie tekstu, spisanego, np. w notatniku.<\/strong><\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Aplikacja bankowa umo\u017cliwia klientom zak\u0142adanie kont bankowych. Klienci mog\u0105 posiada\u0107 wi\u0119cej ni\u017c jedno konto w banku. Klient ma mo\u017cliwo\u015b\u0107 wp\u0142aty i wyp\u0142aty pieni\u0119dzy w ramach posiadanego konta bankowego oraz mo\u017cliwo\u015b\u0107 wykonywania przelewu mi\u0119dzy kontami.<\/p>\n\n\n\n<ol class=\"wp-block-list\" start=\"2\">\n<li><strong>Wybranie rzeczownik\u00f3w i czasownik\u00f3w z opisu.<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Rzeczowniki: Aplikacja, Bank, Klient, Konto, Przelew,<\/li>\n\n\n\n<li>Czasowniki: Zak\u0142adanie kont, wp\u0142ata, wyp\u0142ata, wykonywanie przelewu.<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\" start=\"3\">\n<li><strong>Karty CRC \u2013 Class Responsibility Collaborators, po prostu tabelki.<\/strong><\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Korzystaj\u0105c z kart CRC zastanowi\u0119 si\u0119 jakie elementy, atrybuty b\u0119d\u0105 wchodzi\u0142y w sk\u0142ad klas oraz jak b\u0119d\u0105 ze sob\u0105 po\u0142\u0105czone w jakich relacjach, zale\u017cno\u015bciach. Karty CRC s\u0142u\u017c\u0105 do przedstawienia dla konkretnej klasy (Class) jej odpowiedzialno\u015bci (Responsibilities) oraz powi\u0105za\u0144, relacji (Collaborators) z innymi klasami w ramach tworzonego systemu.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Uwaga: Dla uproszczenia przyk\u0142adu, karty CRC zastosuj\u0119 tylko dla rzeczownik\u00f3w: Klient i Konto.<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th><strong>Class<\/strong><\/th><th>Klient<\/th><\/tr><\/thead><tbody><tr><td><strong>Responsibility<\/strong><\/td><td><strong>Collaborators<\/strong><\/td><\/tr><tr><td><span style=\"text-decoration: underline;\">Przechowuje (HAS-A) dane klienta:<\/span><br>\u2013 Imi\u0119, Nazwisko, Adres, Lista Kont.<br><span style=\"text-decoration: underline;\">Wykonuje:<\/span><br>&#8211; Zak\u0142adanie kont.<\/td><td>Konto (klasa).<\/td><\/tr><\/tbody><\/table><figcaption class=\"wp-element-caption\">Karta CRC dla klasy Klient (rzeczownik ze s\u0142ownego opisu aplikacji).<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th><strong>Class<\/strong><\/th><th>Konto<\/th><\/tr><\/thead><tbody><tr><td><strong>Responsibility<\/strong><\/td><td><strong>Collaborators<\/strong><\/td><\/tr><tr><td><span style=\"text-decoration: underline;\">Przechowuje (HAS-A) dane konta:<\/span><br>\u2013 Numer,  \u015arodki na koncie, Stan konta.<br><span style=\"text-decoration: underline;\">Wykonuje:<\/span><br>&#8211; Wp\u0142ata, Wyp\u0142ata.<\/td><td>Brak.<\/td><\/tr><\/tbody><\/table><figcaption class=\"wp-element-caption\">Karta CRC dla klasy Konto (rzeczownik ze s\u0142ownego opisu aplikacji).<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Uwaga: Dla uproszczenia przyk\u0142adu pomin\u0119 wa\u017cny krok jakim jest projekt i od razu przedstawi\u0119 kod klas Klient i Konto w j\u0119zyku Java.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Wykorzystuj\u0105c rzeczowniki ze s\u0142ownego opisu oraz posi\u0142kuj\u0105c si\u0119 kartami CRC stworz\u0119 nowe klasy Java, natomiast czasowniki pos\u0142u\u017c\u0105 jako metody w tworzonych klasach. Uwaga: metody b\u0119d\u0105 tzw. &#8220;metodami wydmuszkami&#8221;, czyli nic nie zwracaj\u0105, nie przyjmuj\u0105 parametr\u00f3w oraz nie maj\u0105 cia\u0142a, implementacji. Nazwy klas zapisz\u0119 w j\u0119zyku angielskim, poniewa\u017c znacz\u0105ca wi\u0119kszo\u015b\u0107 projekt\u00f3w, kod \u017ar\u00f3d\u0142owy pisze si\u0119 w j\u0119zyku angielskim.<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ Klas Klient, rzeczownik ze s\u0142ownego opisu + karta CRC.\npublic class Client {\n    \/\/ Atrybuty klasy\n    private String firstName;\n    private String lastName;\n    private String address;\n    private List&lt;Account> accounts;\n\n    \/\/ Metody klasy\n    void createAccount() {}\n}<\/pre>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ Klas Konto, rzeczownik ze s\u0142ownego opisu + karta CRC.\npublic class Account {\n    \/\/ Atrybuty klasy\n    private String number;\n    private BigDecimal balance;\n    private boolean active;\n\n    \/\/ Metody klasy\n    public void debit() {}\n    public void credit() {}\n}<\/pre>\n<\/div>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-dots\"\/>\n\n\n\n<p class=\"wp-block-paragraph\">Powy\u017cej przedstawione <strong>praktyczne podej\u015bcie<\/strong>, od kt\u00f3rego zaczynam tworzenie ka\u017cdej aplikacji, <strong>to analiza<\/strong>, kt\u00f3ra bardzo dobrze si\u0119 sprawdza, poprzedza ona wszystkie kolejne kroki. W telegraficznym skr\u00f3cie analiza <strong>pomaga spojrze\u0107 na tworzone oprogramowanie z szerszej perspektywy<\/strong>, co pozwoli nam dok\u0142adniej zrozumie\u0107 tworzony kod. Przez aplikacj\u0119 rozumiem dowolny program, kod \u017ar\u00f3d\u0142owy tworzony w dowolnym, obiektowym j\u0119zyku programowania. W tym przypadku b\u0119dzie, to j\u0119zyk Java. Tworzon\u0105 aplikacj\u0105 mo\u017ce by\u0107 aplikacja: konsolowa (CLI), desktop (GUI) lub web (HTML, REST). Jak wida\u0107 praktyczne podej\u015bcie, kt\u00f3re przedstawiam ma bardzo szerokie zastosowanie. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Moim zdaniem nie nale\u017cy rozpoczyna\u0107 pisania kodu \u017ar\u00f3d\u0142owego bez analizy &#8211; rekomenduj\u0119 nast\u0119puj\u0105c\u0105 \u015bcie\u017ck\u0119: analiza, projekt, implementacja (wsparta testami) &#8211; szerzej opisa\u0142em, to w artykule <a href=\"https:\/\/www.juniorjavadeveloper.pl\/en\/2020\/11\/17\/stop-zanim-zaczniesz-pisac-kod-zastanow-sie-co-chcesz-kodowac-analiza-projekt-i-implementacja\/\" data-type=\"post\" data-id=\"1238\">Stop! Zanim zaczniesz pisa\u0107 kod zastan\u00f3w si\u0119, co chcesz kodowa\u0107? Analiza, projekt i implementacja<\/a>. Programowanie &#8220;na kowboja&#8221; jeszcze nigdy si\u0119 nie sprawdzi\u0142o. Oczywi\u015bcie wsp\u00f3\u0142czesne \u015brodowiska programistyczne (IDE) wspieraj\u0105 i automatyzuj\u0105 proces refaktoryzacji, zmiany istniej\u0105cego kodu \u017ar\u00f3d\u0142owego, ale zawsze wyd\u0142u\u017ca, to czas pisania aplikacji i powoduje niepotrzebne problemy, komplikacje.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Wy\u017cej wspomniana analiza pozwoli wyodr\u0119bni\u0107 model dziedziny dla tworzonej aplikacji. Przyk\u0142adowy model dziedziny dla &#8220;aplikacji bankowej&#8221;:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Application, Bank, Client, Account, Transfer.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Czym jest model dziedziny? W du\u017cym uproszczeniu to s\u0142ownik g\u0142\u00f3wnych poj\u0119\u0107 u\u017cywanych w aplikacji. Sk\u0105d akurat taki, a nie inny model dziedziny? Jak taki model dziedziny zosta\u0142 &#8220;wybrany&#8221; dla &#8220;aplikacji bankowej&#8221;? Wybrany on zosta\u0142y w kolejnych krokach zgodnie z artyku\u0142em <a href=\"https:\/\/www.juniorjavadeveloper.pl\/en\/2020\/11\/17\/stop-zanim-zaczniesz-pisac-kod-zastanow-sie-co-chcesz-kodowac-analiza-projekt-i-implementacja\/\">Stop! Zanim zaczniesz pisa\u0107 kod zastan\u00f3w si\u0119, co chcesz kodowa\u0107? Analiza, projekt i implementacja<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Na podstawie modelu dziedziny powstan\u0105 klasy j\u0119zyka Java. Mo\u017ce si\u0119&nbsp;wydawa\u0107, \u017ce wybrane pi\u0119\u0107 klas &#8211; Application, Bank, Client, Account, Transfer &#8211; to ma\u0142o, ale jak si\u0119 okazuje, to ca\u0142kiem spora ilo\u015b\u0107, kt\u00f3ra pozwoli na stworzenie g\u0142\u00f3wnego modu\u0142u w aplikacji bankowej. Pi\u0119\u0107 klas pozwoli r\u00f3wnie\u017c na &#8220;wygenerowanie&#8221; du\u017cej ilo\u015bci kodu.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Czytaj\u0105c powy\u017csze mo\u017ce pojawi\u0107 si\u0119 kilka pyta\u0144:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Co w przypadku, kiedy musz\u0119 wprowadzi\u0107 tylko drobn\u0105 zmian\u0119 w kodzie?\n<ul class=\"wp-block-list\">\n<li>Moim zdaniem, w tym przypadku r\u00f3wnie\u017c warto stosowa\u0107 \u015bcie\u017ck\u0119: analiza, projekt i implementacja. Dodatkowo nale\u017cy bardzo dobrze zna\u0107 model dziedziny dla aplikacji, z kt\u00f3r\u0105 pracujemy.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Czy do\u015bwiadczony programista r\u00f3wnie\u017c stosuje \u015bcie\u017ck\u0119: analiza, projekt i implementacja?\n<ul class=\"wp-block-list\">\n<li>Tak, do\u015bwiadczony programista r\u00f3wnie\u017c stosuje opisywan\u0105 \u015bcie\u017ck\u0119, przeprowadza w g\u0142owie proces analizy, projektu, a nast\u0119pnie implementacji. Dla bardziej z\u0142o\u017conych aplikacji tworzy niezb\u0119dn\u0105 dokumentacj\u0119.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Czy zawsze trzeba stosowa\u0107 takie podej\u015bcie?\n<ul class=\"wp-block-list\">\n<li>Rekomenduj\u0119 stosowanie \u015bcie\u017cki: analiza, projekt i implementacja. Sp\u00f3jrzmy na to z innej perspektywy. Analiza, to: zastanowienie si\u0119, przemy\u015blenie zagadnienia czysto teoretycznie; projekt, to: formalizacja, dokumentacja naszych przemy\u015ble\u0144; implementacja, to: praktyczne zastosowanie naszych przemy\u015ble\u0144 w oparciu o formaln\u0105 dokumentacj\u0119.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Nale\u017cy zwr\u00f3ci\u0107 uwag\u0119 na bardzo wa\u017cny element, kt\u00f3ry wy\u0142oni\u0142 si\u0119 w fazie analizy, a mianowicie model dziedziny. Wiemy ju\u017c, \u017ce w du\u017cym uproszczeniu to s\u0142ownik g\u0142\u00f3wnych poj\u0119\u0107 u\u017cywanych w aplikacji. To poj\u0119cia, kt\u00f3rymi b\u0119dziemy pos\u0142ugiwa\u0107 si\u0119 w ramach zespo\u0142u programist\u00f3w, analityk\u00f3w biznesowych i os\u00f3b zlecaj\u0105cych nam stworzenie aplikacji. <\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-dots\"\/>\n\n\n\n<p class=\"wp-block-paragraph\">Poni\u017cej poka\u017c\u0119 jak mo\u017ce wygl\u0105da\u0107 kod Java dla naszego g\u0142\u00f3wnego modelu dziedziny, czyli klas: Application, Bank, Client, Account, Transfer. Jest to uproszczony model dziedziny bez dodatkowych z\u0142o\u017conych relacji, np. bez dodatkowej klasy Address dane przechowuje w polu typu String, czyli <code data-enlighter-language=\"java\" class=\"EnlighterJSRAW\">private String address;<\/code> zamiast <code data-enlighter-language=\"java\" class=\"EnlighterJSRAW\">private Address address;<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Wa\u017cnym elementem, kt\u00f3ry wi\u0105\u017ce si\u0119 z wybranymi klasami s\u0105 relacje mi\u0119dzy tymi klasami, relacje mo\u017cemy podzieli\u0107 na dwie g\u0142\u00f3wne &#8220;kategorie&#8221;: IS-A oraz HAS-A. W telegraficznym skr\u00f3cie: <strong>Relacja IS-A (jest)<\/strong> \u2013 dziedziczenie (inheritance), np.: Car IS-A Vehicle \u2013 Samoch\u00f3d jest Pojazdem. <strong>Relacja HAS-A (ma)<\/strong> \u2013 kompozycja (composition), np.:  Car HAS-A Engine \u2013 Samoch\u00f3d ma Silnik. Dodatkowe informacje <a rel=\"noreferrer noopener\" href=\"https:\/\/www.w3resource.com\/java-tutorial\/inheritance-composition-relationship.php\" target=\"_blank\">Inheritance (IS-A) vs. Composition (HAS-A) Relationship<\/a>.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ Model dziedziny dla rzeczownika Application\n\/\/ Ta klasa b\u0119dzie \"punktem wej\u015bcia\", b\u0119dzie zawiera\u0107\n\/\/ kod \u017ar\u00f3d\u0142owy \"dzia\u0142aj\u0105cej aplikacji bankowej\"\npublic class Application {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        Bank juniorBank = new Bank();\n    }\n}<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ Model dziedziny dla rzeczownika Bank\npublic class Bank {\n    private String name;\n    private String address;\n    private List&lt;Client> clients;\n}<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ Model dziedziny dla rzeczownika Client\npublic class Client {\n    private String firstName;\n    private String lastName;\n    private String address;\n    private List&lt;Account> accounts;\n}<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ Model dziedziny dla rzeczownika Account\npublic class Account {\n    private String number;\n    private BigDecimal balance;\n    private boolean active;\n}<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ Model dziedziny dla rzeczownika Transfer\npublic class Transfer {\n    private Account accountFrom;\n    private Account accountTo;\n    private BigDecimal amount;\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Poni\u017cej zaprezentuj\u0119 powy\u017csze klasy uzupe\u0142nione o implementacj\u0119, czyli kod \u017ar\u00f3d\u0142owy. <strong>Uwaga: Dla uproszczenia przyk\u0142adu pomin\u0119 wa\u017cny krok jakim jest projekt i od razu przedstawi\u0119 kod klas w j\u0119zyku Java.<\/strong> B\u0119dzie, to bardzo uproszczona implementacja, tak, aby nie zaciemni\u0107 idei, kt\u00f3ra przy\u015bwieca praktycznemu przyk\u0142adowi, czyli stworzeniu aplikacji bankowej poprzedzonej procesem analizy. Zdaj\u0119 sobie spraw\u0119, \u017ce w wielu miejscach mo\u017cna by\u0142o napisa\u0107 kod lepiej, bardziej zgodnie ze sztuk\u0105.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Kod poni\u017cej nie b\u0119dzie zawiera\u0142 szczeg\u00f3\u0142owego opisu implementacji, ale b\u0119dzie zawiera\u0142 nawi\u0105zania do procesu analizy &#8211; s\u0142owny opis, rzeczowniki i czasowniki oraz karty CRC.<\/p>\n\n\n\n<div class=\"wp-block-columns alignwide is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ Model dziedziny dla rzeczownika Bank ze s\u0142ownego opisu + karta CRC.\npublic class Bank {\n    \/\/ Atrybuty klasy\n    private String name;\n    private String address;\n    private List&lt;Client> clients = new ArrayList&lt;>();\n\n    \/\/ Metoda klasy\n    public Client openClientAccount(Client client) {\n        Account openedClientAccount = client.createAccount();\n        this.clients.add(client);\n\n        return client;\n    }\n\n    \/\/ Metoda klasy\n    public List&lt;Client> listAllClients() {\n        return this.clients;\n    }\n}<\/pre>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns alignwide is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ Model dziedziny dla rzeczownika Client ze s\u0142ownego opisu + karta CRC.\npublic class Client {\n    \/\/ Atrybuty klasy - Responsibility z karty CRC.\n    private String firstName;\n    private String lastName;\n    private String address;\n    private List&lt;Account> accounts = new ArrayList&lt;>();\n\n    public Client(String firstName, String lastName, String address) {\n        this.firstName = firstName;\n        this.lastName = lastName;\n        this.address = address;\n    }\n\n    \/\/ Metoda klasy - Responsibility z karty CRC.\n    public Account createAccount() {\n        Account account = new Account(BigDecimal.ZERO, true);\n        this.accounts.add(account);\n\n        return account;\n    }\n\n    \/\/ Metoda klasy\n    public Account findAccountByNumber(String accountNumber) {\n        for (Account account : accounts) {\n            if (account.number.equals(accountNumber)) {\n                return account;\n            }\n        }\n        return null;\n    }\n}<\/pre>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns alignwide is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ Model dziedziny dla rzeczownika Account ze s\u0142ownego opisu + karta CRC.\npublic class Account {\n    \/\/ Atrybuty klasy - Responsibility z karty CRC.\n    public final String number = UUID.randomUUID().toString();\n    private BigDecimal balance;\n    private boolean active;\n\n    public Account(BigDecimal balance, boolean active) {\n        this.balance = balance;\n        this.active = active;\n    }\n\n    \/\/ Metoda klasy - Responsibility z karty CRC.\n    public void debit(BigDecimal amount) {\n        if (active) {\n            if (this.balance.compareTo(amount) > 0) {\n                this.balance = this.balance.subtract(amount);\n            }\n        }\n    }\n\n    \/\/ Metoda klasy - Responsibility z karty CRC.\n    public void credit(BigDecimal amount) {\n        if (active) {\n            this.balance = this.balance.add(amount);\n        }\n    }\n}<\/pre>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns alignwide is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ Model dziedziny dla rzeczownika Transfer ze s\u0142ownego opisu + karta CRC.\npublic class Transfer {\n    \/\/ Atrybuty klasy\n    private Account accountFrom;\n    private Account accountTo;\n    private BigDecimal amount;\n\n    public Transfer(Account accountFrom, Account accountTo, BigDecimal amount) {\n        this.accountFrom = accountFrom;\n        this.accountTo = accountTo;\n        this.amount = amount;\n    }\n\n    \/\/ Metoda klasy\n    public void makeTransfer() {\n        accountFrom.debit(amount);\n        accountTo.credit(amount);\n    }\n}<\/pre>\n<\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Poni\u017cej klasa zawieraj\u0105ca cz\u0119\u015b\u0107 &#8220;interaktywn\u0105&#8221; tworzonej aplikacji. W niej zostanie stworzony konkretny Bank, Klienci zarejestruj\u0105 si\u0119 w Banku i utworz\u0105 w nim swoje Konta, a nast\u0119pnie wp\u0142ac\u0105 \u015brodki na te konta. Na samym ko\u0144cu zostanie wykonany Przelew mi\u0119dzy r\u00f3\u017cnymi Kontami Bankowymi. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;Aplikacja bankowa&#8221; b\u0119dzie dzia\u0142a\u0107 w trybie konsoli, tzw. &#8220;czarnym okienku&#8221;, bez graficznego interfejsu u\u017cytkownika. Nie zmienia, to faktu, \u017ce mo\u017cemy dla powy\u017cszego kodu stworzy\u0107 aplikacj\u0119 desktop z GUI lub web na www. <\/p>\n\n\n\n<div class=\"wp-block-columns alignwide is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">public class Application {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n\n        System.out.println(\"Witamy w Junior Bank!\");\n        System.out.println(\"Zarejestruj si\u0119 i otw\u00f3rz konto.\\n\");\n\n        System.out.println(\"Podaj swoje imi\u0119:\");\n        String firstName = scanner.nextLine();\n        System.out.println(\"Podaj swoje nazwisko:\");\n        String lastName = scanner.nextLine();\n        System.out.println(\"Podaj sw\u00f3j adres:\");\n        String address = scanner.nextLine();\n\n        \/\/ pierwszy klient jest tworzony na podstawie\n        \/\/ danych wprowadzonych z konsoli\n        Client firstClient = new Client(firstName, lastName, address);\n        \/\/ dla uproszczenia drugi klient jest tworzony\n        \/\/ bez wprowadzania danych z konsoli\n        Client secondClient = new Client(\"Jan\", \"Kowalski\", \"Ul. Kr\u00f3tka 2\");\n\n        Bank juniorBank = new Bank();\n        juniorBank.openClientAccount(firstClient);\n        juniorBank.openClientAccount(secondClient);\n\n        System.out.println(\"\\nRejestracja zako\u0144czona, konto zosta\u0142o utworzone.\");\n        System.out.println(\"Szczeg\u00f3\u0142owe dane klient i konta:\\n\" + firstClient);\n\n        System.out.println(\"\\n__________________________________________________\");\n        System.out.println(\"Wszyscy klienci w JuniorBank:\\n\");\n        List&lt;Client> allClients = juniorBank.listAllClients();\n        allClients.forEach(System.out::println);\n\n        System.out.println(\"\\n__________________________________________________\");\n        System.out.println(\"Przed wykonaniem przelewu wp\u0142a\u0107 \u015brodki na konto.\\n\");\n        System.out.println(\"Wyszukaj konto nadawcy po numerze:\");\n        String senderAccNumber = scanner.nextLine();\n        System.out.println(\"Wyszukaj konto nadawcy po numerze:\");\n        String receiverAccNumber = scanner.nextLine();\n\n        Account senderAccount = firstClient.findAccountByNumber(senderAccNumber);\n        System.out.println(\"Konto nadawcy: \" + senderAccount);\n        Account receiverAccount = secondClient.findAccountByNumber(receiverAccNumber);\n        System.out.println(\"Konto odbiorcy: \" + receiverAccount);\n\n        \/\/ zasilenie kont, przelew na w\u0142asne konto\n        senderAccount.credit(BigDecimal.valueOf(60));\n        receiverAccount.credit(BigDecimal.valueOf(40));\n\n        System.out.println(\"\\n__________________________________________________\");\n        System.out.println(\"Wykonaj przelew mi\u0119dzy kontami.\\n\");\n        System.out.println(\"Konto nadawcy (przed przelewem): \" + senderAccount);\n        System.out.println(\"Konto odbiorcy (przed przelewem): \" + receiverAccount);\n\n        Transfer giftTransfer =\n                new Transfer(senderAccount, receiverAccount, BigDecimal.TEN);\n        giftTransfer.makeTransfer();\n        System.out.println(\"Konto nadawcy (po przelewie): \" + senderAccount);\n        System.out.println(\"Konto odbiorcy (po przelewie): \" + receiverAccount);\n    }\n}<\/pre>\n<\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Poni\u017cej wynik dzia\u0142ania cz\u0119\u015bci &#8220;interaktywnej&#8221; stworzonej aplikacji.<\/p>\n\n\n\n<div class=\"wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Witamy w Junior Bank!\nZarejestruj si\u0119 i otw\u00f3rz konto.\n\nPodaj swoje imi\u0119:\nJan\nPodaj swoje nazwisko:\nKowalski\nPodaj sw\u00f3j adres:\nUl. D\u0142uga 1\n\nRejestracja zako\u0144czona, konto zosta\u0142o utworzone.\nSzczeg\u00f3\u0142owe dane klient i konta:\nClient{firstName='Jan', lastName='Kowalski', address='Ul. D\u0142uga 1', \naccounts=[Account{number='9db92b6e-05fc-4918-901e-4e3eb86cffe3', balance=0, active=true}]}\n\n\n__________________________________________________\nWszyscy klienci w JuniorBank:\n\nClient{firstName='Jan', lastName='Kowalski', address='Ul. D\u0142uga 1', \naccounts=[Account{number='9db92b6e-05fc-4918-901e-4e3eb86cffe3', balance=0, active=true}]}\n\nClient{firstName='Jan', lastName='Nowak', address='Ul. Kr\u00f3tka 2', \naccounts=[Account{number='1520230c-178f-4be2-962d-61e5efdf19b3', balance=0, active=true}]}\n\n\n__________________________________________________\nPrzed wykonaniem przelewu wp\u0142a\u0107 \u015brodki na konto.\n\nWyszukaj konto nadawcy po numerze:\n9db92b6e-05fc-4918-901e-4e3eb86cffe3\nWyszukaj konto nadawcy po numerze:\n1520230c-178f-4be2-962d-61e5efdf19b3\nKonto nadawcy: Account{number='9db92b6e-05fc-4918-901e-4e3eb86cffe3', balance=0, active=true}\nKonto odbiorcy: Account{number='1520230c-178f-4be2-962d-61e5efdf19b3', balance=0, active=true}\n\n__________________________________________________\nWykonaj przelew mi\u0119dzy kontami.\n\nKonto nadawcy (przed przelewem): Account{number='9db92b6e-05fc-4918-901e-4e3eb86cffe3', balance=60, active=true}\nKonto odbiorcy (przed przelewem): Account{number='1520230c-178f-4be2-962d-61e5efdf19b3', balance=40, active=true}\n\nKonto nadawcy (po przelewie): Account{number='9db92b6e-05fc-4918-901e-4e3eb86cffe3', balance=50, active=true}\nKonto odbiorcy (po przelewie): Account{number='1520230c-178f-4be2-962d-61e5efdf19b3', balance=50, active=true}\n\nProcess finished with exit code 0\n<\/pre>\n<\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Patrz\u0105c na powy\u017cszy kod, \u015bmia\u0142o mo\u017cna stwierdzi\u0107, \u017ce &#8220;niewiele zmieni\u0142o si\u0119&#8221; od etapu analizy. S\u0142owny opis pozwoli\u0142 wy\u0142oni\u0107 rzeczowniki i czasowniki, kt\u00f3re przekszta\u0142ci\u0142y si\u0119 w model dziedziny. Na tej podstawie powsta\u0142y karty CRC, kt\u00f3re nast\u0119pnie zamieni\u0142y si\u0119 w klasy j\u0119zyka Java.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th><strong>Class<\/strong><\/th><th>Klient<\/th><\/tr><\/thead><tbody><tr><td><strong>Responsibility<\/strong><\/td><td><strong>Collaborators<\/strong><\/td><\/tr><tr><td><span style=\"text-decoration: underline;\">Przechowuje (HAS-A) dane klienta:<\/span><br>\u2013 Imi\u0119, Nazwisko, Adres, Lista Kont.<br><span style=\"text-decoration: underline;\">Wykonuje:<\/span><br>&#8211; Zak\u0142adanie kont.<\/td><td>Konto (klasa).<\/td><\/tr><\/tbody><\/table><figcaption class=\"wp-element-caption\">Karta CRC dla klasy Klient (rzeczownik ze s\u0142ownego opisu aplikacji).<\/figcaption><\/figure>\n\n\n\n<div class=\"wp-block-columns alignwide is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ Model dziedziny dla rzeczownika Client ze s\u0142ownego opisu + karta CRC.\npublic class Client {\n    \/\/ Atrybuty klasy - Responsibility z karty CRC.\n    private String firstName;\n    private String lastName;\n    private String address;\n    private List&lt;Account> accounts = new ArrayList&lt;>();\n\n    public Client(String firstName, String lastName, String address) {\n        this.firstName = firstName;\n        this.lastName = lastName;\n        this.address = address;\n    }\n\n    \/\/ Metoda klasy - Responsibility z karty CRC.\n    public Account createAccount() {\n        Account account = new Account(BigDecimal.ZERO, true);\n        this.accounts.add(account);\n\n        return account;\n    }\n\n    \/\/ Metoda klasy\n    public Account findAccountByNumber(String accountNumber) {\n        for (Account account : accounts) {\n            if (account.number.equals(accountNumber)) {\n                return account;\n            }\n        }\n        return null;\n    }\n}<\/pre>\n<\/div>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-dots\"\/>\n\n\n\n<p class=\"wp-block-paragraph\">Poni\u017cej elementy, kt\u00f3re zosta\u0142y dodane w trakcie implementacji, a nie by\u0142y uwzgl\u0119dnione w analizie.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Konstruktory dla klas <code>Client<\/code>, <code>Account<\/code> oraz <code>Transfer<\/code>:\n<ul class=\"wp-block-list\">\n<li><code data-enlighter-language=\"java\" class=\"EnlighterJSRAW\">public Client(String firstName, String lastName, String address) {}<\/code>,<\/li>\n\n\n\n<li><code data-enlighter-language=\"java\" class=\"EnlighterJSRAW\">public Account(BigDecimal balance, boolean active) {}<\/code>,<\/li>\n\n\n\n<li><code data-enlighter-language=\"java\" class=\"EnlighterJSRAW\">public Transfer(Account accountFrom, Account accountTo, BigDecimal amount) {}<\/code>.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Dwie metody &#8220;pomocnicze&#8221; w klasie <code>Bank<\/code> oraz <code>Client<\/code>: \n<ul class=\"wp-block-list\">\n<li><code data-enlighter-language=\"java\" class=\"EnlighterJSRAW\">public List&lt;Client&gt; listAllClients() {}<\/code>,<\/li>\n\n\n\n<li><code data-enlighter-language=\"json\" class=\"EnlighterJSRAW\">public Account findAccountByNumber(String accountNumber) {}<\/code>.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Poni\u017cej elementy, kt\u00f3re wymagaj\u0105 g\u0142\u0119bszego zastanowienie i modyfikacji.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Generowanie unikalnych numer\u00f3w kont bankowych &#8211; na pewno zmieni\u0142bym obecn\u0105 &#8220;implementacj\u0119&#8221; &#8211; <code data-enlighter-language=\"java\" class=\"EnlighterJSRAW\">public final String number = UUID.randomUUID().toString();<\/code>.<\/li>\n\n\n\n<li>Klasa <code>Transfer<\/code> oraz jej metoda <code data-enlighter-language=\"java\" class=\"EnlighterJSRAW\">public void makeTransfer() {}<\/code> :\n\n\n\n\n\n\n<ul class=\"wp-block-list\">\n<li>Metoda mog\u0142aby przyjmowa\u0107 parametry &#8211; <code data-enlighter-language=\"java\" class=\"EnlighterJSRAW\">public void makeTransfer(Account accountFrom, Account accountTo, BigDecimal amount) {}<\/code>,<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li>W klasie <code>Transfer<\/code> zrezygnowa\u0142bym z konstruktora i nie przechowywa\u0142 bym stanu, danych w atrybutach klasy. Dzi\u0119ki temu klasa Transfer sta\u0142a by si\u0119 klas\u0105 narz\u0119dziow\u0105.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Podsumowuj\u0105c, przedstawiona aplikacja bankowa sk\u0142ada si\u0119 z pi\u0119ciu klas, w kt\u00f3rych w sumie jest oko\u0142o 100 linii kodu, &#8220;dodatkowe&#8221; 60 linii kodu stanowi sama cz\u0119\u015b\u0107 &#8220;interaktywna&#8221; aplikacji. Na podstawie analizy powsta\u0142o 160 linii kodu, w fazie implementacji doda\u0142em cztery elementy &#8211; dwie metody i dwa konstruktory &#8211; zaproponowa\u0142em trzy modyfikacje. Dzi\u0119ki analizie unikn\u0105\u0142em niepotrzebnej refaktoryzacji, zmiany kodu \u017ar\u00f3d\u0142owego. Kto\u015b m\u00f3g\u0142by powiedzie\u0107, \u017ce do\u015bwiadczony programista tak by zrobi\u0142, ale nie m\u0142odszy programista, programistka. Z biegiem czasu i po wykonaniu kilku takich &#8220;aplikacji&#8221; zgodnie ze \u015bcie\u017ck\u0105 &#8211; analiza, projekt i implementacja &#8211; mniej do\u015bwiadczone osoby nabra\u0142by wprawy. Zach\u0119cam do porzucenia programowania &#8220;na kowboja&#8221; na rzecz \u015bcie\u017cki opisanej w tym artykule.<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-wp-embed is-provider-poradnik-dla-przysz-ych-junior-java-developer-039-w wp-block-embed-poradnik-dla-przysz-ych-junior-java-developer-039-w\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"xKE3fM2jKW\"><a href=\"https:\/\/www.juniorjavadeveloper.pl\/en\/kontakt\/\">Contact<\/a><\/blockquote><iframe loading=\"lazy\" class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; visibility: hidden;\" title=\"\u201eKontakt\u201d \u2014 Poradnik dla przysz\u0142ych Junior Java Developer&amp;apos;\u00f3w\" src=\"https:\/\/www.juniorjavadeveloper.pl\/kontakt\/embed\/#?secret=1y33DNDD8I#?secret=xKE3fM2jKW\" data-secret=\"xKE3fM2jKW\" width=\"600\" height=\"338\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n\n\n\n<figure class=\"wp-block-embed is-type-wp-embed is-provider-poradnik-dla-przysz-ych-junior-java-developer-039-w wp-block-embed-poradnik-dla-przysz-ych-junior-java-developer-039-w\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"kTtQjr0Heq\"><a href=\"https:\/\/www.juniorjavadeveloper.pl\/en\/mentoring-rezerwuj-termin\/\">Mentoring - book an appointment<\/a><\/blockquote><iframe loading=\"lazy\" class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; visibility: hidden;\" title=\"\u201eMentoring \u2013 rezerwuj termin\u201d \u2014 Poradnik dla przysz\u0142ych Junior Java Developer&amp;apos;\u00f3w\" src=\"https:\/\/www.juniorjavadeveloper.pl\/mentoring-rezerwuj-termin\/embed\/#?secret=C8EPPtUyPt#?secret=kTtQjr0Heq\" data-secret=\"kTtQjr0Heq\" width=\"600\" height=\"338\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Zdj\u0119cie autorstwa <a href=\"https:\/\/www.pexels.com\/photo\/typewriter-1750268\/\" data-type=\"URL\" data-id=\"https:\/\/www.pexels.com\/photo\/typewriter-1750268\/\" target=\"_blank\" rel=\"noreferrer noopener\">Suzy Hazelwood<\/a> z <a rel=\"noreferrer noopener\" href=\"https:\/\/www.pexels.com\/pl-pl\/\" target=\"_blank\">Pexels<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>Tym razem artyku\u0142 rozpoczn\u0119 praktycznym przyk\u0142adem, kt\u00f3ry zobrazuje moje podej\u015bcie, od kt\u00f3rego zaczynam tworzenia aplikacji. Chc\u0119 pokaza\u0107 jak &#8220;proste&#8221; i skuteczne jest, to podej\u015bcie. Nast\u0119pnie, w dalszej cz\u0119\u015bci opisz\u0119, co, jak i dlaczego zrobi\u0142em. Wyobra\u017amy sobie, \u017ce zosta\u0142em poproszony o napisanie wersji demonstracyjnej, tzw. Proof of Concept aplikacji bankowej. Od czego zacz\u0105\u0107? Nie wpada\u0107 w [&hellip;]<\/p>","protected":false},"author":1,"featured_media":2512,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_ppp_document_settings_meta":"","footnotes":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false}}},"categories":[6,3,2,7],"tags":[],"class_list":["post-2446","post","type-post","status-publish","format-standard","has-post-thumbnail","category-felieton","category-kod-java","category-poczatkujacy","category-poradnik"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/www.juniorjavadeveloper.pl\/wp-content\/uploads\/2023\/01\/Od-czego-zaczac-tworzenie-aplikacji_przestan-pisac-kod-zrodlowy_Mentor-Junior-Java-Developer.jpg","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/www.juniorjavadeveloper.pl\/en\/wp-json\/wp\/v2\/posts\/2446","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.juniorjavadeveloper.pl\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.juniorjavadeveloper.pl\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.juniorjavadeveloper.pl\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.juniorjavadeveloper.pl\/en\/wp-json\/wp\/v2\/comments?post=2446"}],"version-history":[{"count":77,"href":"https:\/\/www.juniorjavadeveloper.pl\/en\/wp-json\/wp\/v2\/posts\/2446\/revisions"}],"predecessor-version":[{"id":3746,"href":"https:\/\/www.juniorjavadeveloper.pl\/en\/wp-json\/wp\/v2\/posts\/2446\/revisions\/3746"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.juniorjavadeveloper.pl\/en\/wp-json\/wp\/v2\/media\/2512"}],"wp:attachment":[{"href":"https:\/\/www.juniorjavadeveloper.pl\/en\/wp-json\/wp\/v2\/media?parent=2446"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.juniorjavadeveloper.pl\/en\/wp-json\/wp\/v2\/categories?post=2446"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.juniorjavadeveloper.pl\/en\/wp-json\/wp\/v2\/tags?post=2446"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}