---
# System prepended metadata

title: 5  Podnikové aplikace
tags: [řvss, java, pa165, oop]

---

# 5  Podnikové aplikace
###### tags: `řvss`, `java`, `oop`, `pa165`

> Podnikové aplikace. Základní koncepty softwarových architektur. Vrstvená architektura moderních informačních systémů, model-view-controller. Architektura orientovaná na služby (SOA). Nasazení. Základní koncepty cloud computingu. Objektově-relační mapování (ORM) v podnikových aplikacích. Návrhové vzory v rozsáhlých podnikových systémech (Data Transfer Object (DTO), Data Access Object (DAO), Facade, Dependency Injection (DI)). (PA165)

---
<style>
blockquote span {color:#333;}
blockquote span a {color:#337AB7;}
blockquote span code {color:#333;}
</style>

> Príklad
> [color=purple]

> Vysvetlenie
> [color=#0047AB]

> Problém
> [color=orange]

> Riešenie
> [color=lightgreen]

:::info
:bulb: Voľná "definícia"
:::

:::warning
:book: Zdroj, ďalšie čítanie
:::

---

## Podnikové aplikácie (_enterprise applications_)

:::info
:bulb: **Podniková aplikácia** je rozsiahla softvérová platforma, ktorá bola navrhnutá pre použitie vo **firemnom prostredí** (súkromná firma, štátny podnik a pod.). Podnikové aplikácie sú komplexné, škálovateľné, distribuované a založené na komponentoch.
:::

**Podnikové aplikácie**
- sú obvykle určené na prepojenie alebo integráciu s ďalšími podnikovými aplikáciami;
- poskytujú nástroje na modelovanie business procesov organizácie za účelom zvýšenia jej efektívnosti a produktivity;
- sú vyvíjané in-house alebo zakúpené ako hotové riešenia (alebo kombinácia oboch);
  - Hotové riešenia sa hodia pre "štandardné" oblasti, ako napr. účtovné systémy, systémy pre správu ľudských zdrojov a pod.
- sú niekedy poskytované cloudovým modelom software-as-a-service (viď [SaaS](#Modely-služieb-4x));
- umožňujú napr.
  - spravovať zdroje organizácie,
  - ponúkať a predávať služby a produkty zákazníkom,
  - nakupovať služby a produkty od dodávateľov.

> **Podnikový softvér** je súhrnný výraz pre všetky aplikácie, ktoré slúžia pre podporu fungovania organizácie/podniku.
> [color=#0047AB]

> **Príklady** typov podnikových aplikácií:
> [color=purple]
> - systémy pre spracovanie platieb
> - mzdové účtovníctvo
> - systémy pre správu obsahu (CMS)
> - riadenie ľudských zdrojov (HRM)
> - riadenie vzťahov so zákazníkmi (CRM)
> - dochádzkový softvér
> - systémy pre messaging a spoluprácu (e-mail, VOiP, videomeetingy)
> - softvér pre riadenie rizík (Risk Management Software)
> - softvér pre riadenie projektov (Project Management Software)
>
> :::warning
> :book: Viac príkladov napr. [»tu«](https://managementmania.com/cs/eas-enterprise-application-software-podnikovy-software)
> :::

## Základné koncepty softvérových architektúr

:::info
:bulb: **Softvérová architektúra** je základná štruktúra softvérového systému, ktorá sa po implementácii len veľmi ťažko mení. (jedna z možných "definícií")
:::

> _"... the decisions you wish you could get right early in a project."_
> [name=Ralph Johnson]

> **Príklady** softvérových architektúr
> [color=purple]
> - vrstvená (viď [»ďalšia sekcia«](#Vrstvená-architektúra))
> - model-view-controller (viď [»sekcia o MVC«](#Model-view-controller-MVC))
> - architektúra orientovaná na služby (viď [»sekcia o SOA«](#Service-oriented-architecture-SOA))
> - monolitická architektúra
> - klient-server (2-vrstvá, 3-vrstvá, ...)
>   ![](https://www.oreilly.com/library/view/architectural-patterns/9781787287495/assets/43ab3182-df6d-4495-8ce0-c2705abf261f.png "3-tier client-server architecture")
> - peer-to-peer (P2P)
> - udalosťmi riadená architektúra
>   ![](https://www.oreilly.com/library/view/software-architecture-patterns/9781491971437/assets/sapr_0201.png "Event-driven architecture")
> - architektúra mikrokernelu
>   ![](https://www.oreilly.com/library/view/software-architecture-patterns/9781491971437/assets/sapr_0301.png "Microkernel architecture")
> - architektúra mikroslužieb
>   ![](https://www.oreilly.com/library/view/software-architecture-patterns/9781491971437/assets/sapr_0401.png "Microservices architecture")

### Vrstvená architektúra

:::warning
:book: [O'Reilly: Software Architecture Patterns by Mark Richards](https://www.oreilly.com/library/view/software-architecture-patterns/9781491971437/ch01.html)
:::

- De facto štandardná architektúra pre väčšinu Java EE (Enterprise Edition) aplikácií
- Komponenty sú organizované do horizontálnych vrstiev, pričom každá vrstva vykonáva konkrétnu funkciu (prezentačná logika, business logika, ...).
- Vrstvy môžu byť uzavrené (_closed_) alebo otvorené (_open_), otvorené vrstvy sa dajú pri prechode požiadavku vrstvami preskočiť.
  - Otvorené vrstvy môžu zhoršovať vlastnosti aplikácie (porušenie izolácie vrstiev).
- Počet a typ vrstiev nie je pevne daný, väčšina aplikácií má 4 vrstvy:
  - prezentačná vrstva (používateľské rozhranie),
  - _business_ vrstva (logika aplikácie),
  - _persistence_ vrstva (prístup do databázy),
  - databáza.

![](https://www.oreilly.com/library/view/software-architecture-patterns/9781491971437/assets/sapr_0101.png "Layered architecture")

:::success
:ok_hand: **Výhody**
- **oddelenie zodpovednosti** (_separation of concerns_) medzi komponentami = komponenty v danej vrstve riešia výhradne logiku danej vrstvy
- dobrá ako základná architektúra
- **jednoduchý vývoj**
  > _Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization's communication structure._
  > [name=Conway's law]
- **jednoduché testovanie**
  - vrstvy sa dajú pri testovaní úplne odizolovať, napr. pomocou _mockovania_ nižších vrstiev
:::

:::danger
:no_entry_sign: **Nevýhody**
- _"architecture **sinkhole** anti-pattern"_ = požiadavky sa presúvajú medzi vrstvami prakticky bez zmeny ($\Rightarrow$ nie sú vrstvy zvolené nesprávne?)
  - ak max cca 20% požiadaviek je takýchto, je to ešte +- OK
- aplikácia je často **monolit**, čo môže sťažovať nasadenie, zhoršovať robustnosť, spoľahlivosť, výkon a škálovateľnosť
- **nízky výkon**
  - v niektorých prípadoch môže byť prechádzanie vrstvami zbytočne neefektívne
- **zložité nasadenie**
  - malá zmena v jednom komponente môže vyžadovať znovunasadenie (takmer) celej aplikácie -- môže sa stať, že znovunasadenie bude musieť byť naplánované napr. na víkend alebo mimo pracovné hodiny
  - nedá sa jednoducho použiť CD (_continuous delivery_)
- **slabá škálovateľnosť**
:::

### Model-view-controller (MVC)

![](https://www.freecodecamp.org/news/content/images/size/w1600/2021/04/MVC3.png)
:::success
:ok_hand: Výhoda -- **separation of concerns**: oddelenie backendu a frontendu $\rightarrow$ jednoduchšie úpravy v aplikácii.
:::

### Service-oriented-architecture (SOA)

:::info
:bulb: **SOA** (servisne-orientovaná architektúra) je návrhová filozofia; kolekcia služieb, ktoré medzi sebou komunikujú a pre komunikáciu využívajú štandardizované protokoly a dohodnuté rozhrania. Vďaka týmto rozhraniam sa môže meniť implementácia služieb bez toho, aby bola ovplyvnená schopnosť systému služby využívať.
:::

> _**SOA** is an architectural style, realized as a collection of collaborating agents, each called a service, whose goal is to manage complexity and achieve architectural resilience and robustness through ideas such as loose coupling, location transparency, and protocol independence._
> [name=IBM]

> **Služba** je entita, ktorá má popis a ktorá je dostupná cez rozhranie, ktoré umožňuje klientovi službu využívať. Služba v kontexte SOA je sprístupnená časť funkcionality s nasledujúcimi vlastnosťami:
>    1. Kontrakt rozhrania ku službe je **nezávislý na platforme**.
>    2. Služba môže byť dynamicky vyhľadaná a použitá.
>    3. Služba je **sebestačná**; udržiava si svoj vlastný stav.
> [name=PA165][color=#0047AB]

Každý IT prostriedok, systém, aplikácia môže vystupovať ako služba.

> **Príklad SOA:** niektoré služby v **e-shope**[^dzone]
> [color=purple]
> - katalóg produktov
> - platobná brána
> - spracovanie objednávky
> - doprava

[^dzone]: [link](https://dzone.com/articles/service-oriented-architecture-a-dead-simple-explan)

#### Životný cyklus SOA
- návrh,
- kompozícia,
- konzumácia (rôznymi spôsobmi používateľmi, ďalšími systémami).

> [color=#0047AB]
> #### Rozdiel medzi SOA a Web Services
> SOA je spôsob navrhovania systémov, zatiaľ čo Web services je implementačná technológia, ktorá používa špecifické štandardy a protokoly k dosiahnutiu riešenia založeného na princípoch SOA.

:::warning
:book: [FI Wiki: SOA](https://kore.fi.muni.cz/wiki/index.php?title=SOA)
:::

## Nasadenie (_deployment_)

:::info
:bulb: Pod pojmom **nasadenie** sa myslia všetky kroky, procesy a aktivity, ktoré sprístupnia systém alebo jeho novú verziu zamýšľaným používateľom. V súčasnosti vývojári nasadzujú aplikácie a ich aktualizácie pomocou kombinácie manuálnych a automatizovaných procesov.
:::

Odlišujeme dve hlavné **prostredia**:
- **development** environment (kde sa aplikácia vyvíja, testuje),
- live/**production** environment (kam je aplikácia nasadená pre koncových používateľov, napr. cloud -- SaaS alebo app store).

:::info
:bulb: **Softvérové vydanie** (_software release_) je konkrétna verzia kódu a jeho závislostí, ktorá je sprístupnená na nasadenie.
:::

![](https://lvivity.com/wp-content/uploads/2018/01/sdlc.jpg "Software development lifecycle")

:::info
:bulb: **DevOps** je metodológia a sada best practices, ktorá kombinuje vývoj softvéru (Dev) a jeho prevádzkovanie (IT operations -- Ops). Jej hlavným cieľom je skrátiť vývojový cyklus pri zachovaní vysokej kvality softvéru. 
:::

:::info
:bulb: Súčasťou DevOps býva **Continuous Integration (CI)** framework, podľa ktorého sú zmeny pravidelne integrované do zdieľaného repozitára, pokojne aj niekoľkokrát denne. Tento kód je automaticky testovaný za účelom skorého nájdenia (a odstránenia) chýb.
:::

:::info
:bulb: **Continuous Deployment (CD)** popisuje stratégiu nasadzovania softvéru, podľa ktorej nový kód musí prejsť sadou automatizovaných testov než bude (automaticky) uvoľnený do produkčného prostredia. Nutnou podmienkou sú kvalitné testy.
:::

:::warning
:book: [Wikipedia: DevOps](https://en.wikipedia.org/wiki/DevOps)
:::

## Základné koncepty cloud computingu

:::warning
:book: [The NIST Definition of Cloud Computing](https://csrc.nist.gov/publications/detail/sp/800-145/final)
:book: [Techpedia: Cloud Computing](http://techpedia.fel.cvut.cz/download/?fileId=802&objectId=77)
:::

> Cloud computing je v podstate **distribuovaná výpočetná platforma**, ktorá poskytuje svoje prostriedky širokému spektru používateľov na škálovanie, virtualizáciu hardvérovej a/alebo softvérovej infraštruktúry **cez internet**.
> [name=Techpedia][color=#0047AB]

> Cloud computing je model navrhnutý pre umožnenie pohodlného **prístupu ku zdieľaným konfigurovateľným výpočetným zdrojom** (sieťam, serverom, úložiskám, aplikáciám, službám), ktoré môžu byť **okamžite** poskytuné s **minimálnou správou** alebo potrebou zásahu poskytovateľa tejto služby.
> [name=NIST][color=#0047AB]

:::success
:ok_hand: **Výhody**
- služby na vyžiadanie (samoobsluha)
- združovánie zdrojov nezávisle na umiestnení 
- prenos rizika
- nízke zaobstarávacie náklady (netreba veľké investície do infraštruktúry)
- jednoduchá správa
- spoľahlivosť
:::

:::danger
:no_entry_sign: **Nevýhody**
- neisté súkromie a bezpečnosť
- len obmedzená kontrola
- priama závislosť na poskytovateľovi (_vendor lock-in_)
:::

### Základné charakteristiky `5`

Samoobsluha na vyžiadanie
~ Zákazník si môže vyžiadať výpočetné zdroje podľa svojej potreby. Tieto požiadavky sú na strane poskytovateľa riešené automaticky v priebehu pár minút bez nutnosti ľudskej interakcie.

Široký sieťový prístup
~ Prístup k technológii je umožnený **cez sieť** pomocou **rôznych** klientských platforiem (počítače, mobily, webové prehliadače, ...) vďaka použitiu štandardných mechanizmov.

Združovanie zdrojov
~ Zdroje poskytovateľa cloudovej služby sú delené medzi **niekoľkých používateľov** vďaka multi-klientskému modelu (_multi-tenant model_). Rôzne fyzické a virtuálne zdroje sú dynamicky prideľované na vyžiadanie zákazníka. Zákazník nevie, kde konkrétne sa jeho aktuálne zdroje nachádzajú.

Rýchla elasticita
~ Zdroje môžu byť **získané a uvoľnené podľa potreby** (často automaticky), aby pokryli aktuálne požiadavky zákazníka.

Meranie služby
~ Používané zdroje sú **monitorované**, riadené a **reportované** zákazníkovi, čím mu (a tiež aj poskytovateľovi) poskytujú transparentný **prehľad o spotrebe a nákladoch**.

### Modely služieb `3`

Software as a Service (SaaS)
~ Zákazník používa poskytovateľove hotové **aplikácie** (bežiace na cloude), ktoré sú dostupné z rôznych klientských zariadení pomocou tenkého klienta (napr. prehliadač) alebo tučného klienta (špecifická aplikácia).
~ Zákazník nespravuje a ani neriadi cloudovú infraštruktúru bežiacu na pozadí.

  > **Príklady:** GMail, Google Docs, Dropbox, MS Office 365
  > [color=purple]

Platform as a Service (PaaS)
~ Zákazník môže využiť poskytovateľovu platformu pre **nasadenie** (poskytovateľom podporovaných) vlastných alebo získaných **aplikácií**.
~ Zákazník nespravuje a ani neriadi cloudovú infraštruktúru bežiacu na pozadí (sieťové pripojenia, servery, operačné systémy, úložisko), ale má kontrolu nad nasadenými aplikáciami a (možno) aj nad konfiguráciou prostredia, ktoré hostuje tieto aplikácie.

  > **Príklady:** Google App Engine, Heroku
  > [color=purple]

Infrastructure as a Service (IaaS)
~ Poskytovateľ poskytuje zákazníkovi výpočetný výkon, úložisko, sieťové pripojenia a ďalšie základné výpočetné zdroje.
~ Zákazník nespravuje a ani neriadi cloudovú infraštruktúru bežiacu na pozadí, zato však má kontrolu nad operačnými systémami, úložiskom a nasadenými aplikáciami a (možno) obmedzenú kontrolu nad niektorými sieťovými komponentami (napr. firewall).

  > Prakticky sa jedná o podobnú situáciu ako v prípade vlastného hardvéru, avšak nie je potrebné daný hardvér vlastniť, udržiavať a dokupovať/predávať zdroje pri škálovaní.
  > [color=#0047AB]

  > **Príklad:** Google Computing Engine, DigitalOcean, Amazon Web Services (AWS), Microsoft Azure
  > [color=purple]

### Modely nasadenia `4`

Súkromný cloud
~ Infraštruktúru používa výhradne jeden zákazník (organizácia). 
~ Infraštruktúru môže vlastniť, spravovať a poskytovať daná organizácia, tretia strana, alebo kombinácia oboch.
~ Infraštruktúra sa môže nachádzať v priestoroch zákazníka alebo poskytovateľa.

Komunitný cloud
~ Infraštruktúru používa výhradne určitá komunita zákazníkov.
~ Infraštruktúru môže vlastniť, spravovať a poskytovať jedna alebo viacero organizácií z danej komunity, tretia strana, prípadne nejaká ich kombinácia.
~ Infraštruktúra sa môže nachádzať v priestoroch poskytovateľa alebo u zákazníka/zákazníkov.

Verejný cloud
~ Infraštruktúru môže používať široká verejnosť.
~ Infraštruktúru môže vlastniť, spravovať a poskytovať prakticky akákoľvek organizácia alebo kombinácia organizácií.
~ Infraštruktúra sa nachádza v priestoroch poskytovateľa.

Hybridný cloud
~ Voľné spojenie dvoch alebo viacerých rôznych infraštruktúr spomenutých vyššie.

## Objektovo-relačné mapovanie (ORM)

> :dart: Chceme používať relačnú databázu v OOP aplikácii.
> :warning: **Problém:** problematická kompatibilita medzi OOP prístupom a relačným prístupom.
> [color=orange]
>
> Základné nezhody **intuitívne** (viac v [ďalšej sekcii](#Nezhody-medzi-objektami-a-rel%C3%A1ciami-tzv-object-relational-impedance-mismatch3)):
> - Dátové typy v **OOP:** objekty, zoznamy, množiny, mapy, ... (často nie len skalárne hodnoty)
> - Dátové typy v **DB:** skalárne hodnoty (`number`, `varchar`, ...); vzťahy medzi záznamami pomocou _foreign keys_ a ďalších tabuliek
>
> Klasický RDBMS takéto štruktúrované dáta nevie jednoducho spravovať, programátor by musel naimplementovať delenie údajov do tabuliek, obojsmernú konverziu typov všetkých použitých tried a tiež opätovné vytvorenie objektu pomocou skladania údajov z viacerých tabuliek.
>
> > Riešenie: **ORM knižnica**
> > [color=lightgreen]
> > > **Príklad: `JBoss Hibernate`** (Java)
> > > [color=purple]

> [color=#0047AB]
> ### Nezhody medzi objektami a reláciami (tzv. _object-relational impedance mismatch_)[^mismatch-hibernate]
> 
> Rozdielna granularita
> ~ Môže sa stať, že objektový model má napr. viac tried ako je počet odpovedajúcich tabuliek v databázi (napr. reprezentácia adresy).
> 
> Dedičnosť
> ~ V (štandardných) relačných databázach tento koncept neexistuje.
>
> Identita
> ~ V relačných databázach sa rovnosť záznamov určuje podľa primárneho kľúča, zatiaľ čo napr. v Jave existuje identita objektov (`a == b`) a rovnosť objektov (`a.equals(b)`).
> 
> Vzťahy medzi entitami
> ~ V OOP sú vzťahy reprezentované **jednosmernými odkazmi na objekty** (rovnako v zoznamoch, mapách a pod.), zatiaľ čo v RDBMS sa používajú **cudzie kľúče** (_foreign keys_). Ak sú potrebné obojsmerné asociácie, napr. v Jave treba vytvoriť ďalšiu asociáciu pre druhý smer.
>
> Prístup k objektom
> ~ V OOP sa k objektom pristupuje cez **odkazy** z iných objektov (prechádzanie grafu). V relačnej databáze je tento prístup neefektívny; typicky chceme minimalizovať počet **SQL dotazov**, tj. použiť joiny a obmedziť výber na požadované entity než s nimi začneme pracovať.

[^mismatch-hibernate]: https://hibernate.org/orm/what-is-an-orm/

---

:::info
:bulb: **ORM** je programovacia technika, ktorá zaisťuje **automatickú konverziu dát** medzi nekompatibilnými typovými systémami, konkrétne medzi relačnou **databázou** a objektovo orientovaným **programovacím jazykom**.
:::

> Ide o preklad reprezentácie objektov do a z formátu, ktorý sa dá uchovávať v databázi tak, aby zostali zachované vlastnosti a vzťahy objektov. Ak je táto funkcionalita (uloženie a získanie) implementovaná, hovoríme o objektoch, že sú **perzistentné**.
> [color=#0047AB]

> Jednoduchý **príklad:** adresár :notebook_with_decorative_cover: -- každá osoba je jeden objekt.
> Objekt v Jave:
> [color=purple]
> ```java=
> public class Person {
>     private String name;
>     private List<TelephoneNumber> phoneNumbers;
>     private List<String> emailAddresses;
>     private List<Address> addresses;
>
>     // some implementation below
> }
> ```
> Model relačnej databázy (zjednodušený model, ktorý neumožňuje mať jedno tel. číslo/adresu pre viacero osôb, neukladá efektívne adresu a pod.):
> ```mermaid
> erDiagram
>   Person {
>     number id
>     string name
>   }
>   Person ||--o{ PhoneNumber : ""
>   PhoneNumber {
>     number person_id
>     string phone_number
>   }
>   Person ||--o{ EmailAddress : ""
>   EmailAddress {
>     number person_id
>     string email_address
>   }
>   Person ||--o{ Address : ""
>   Address {
>     number person_id
>     string city
>     string street
>     number house_number
>   }
> ```

**Alternatívne riešenia:**
- použiť objektovo-orientovanú databázu (OODBMS) namiesto relačnej (RDBMS);
- použiť dokumentovo-orientovanú databázu (napr. natívnu XML databázu) a k nej ODM (_object-document mapper_) namiesto ORM.

:::warning
:book: [Wikipedia: Object-relational mapping](https://en.wikipedia.org/wiki/Object%E2%80%93relational_mapping)
:::


## Návrhové vzory (_design patterns_)

> **Návrhový vzor** (v softvérovom inžinierstve) je všeobecné znovupoužiteľné riešenie často sa vyskytujúceho návrhového problému. Nejedná sa o hotový návrh, ktorý sa dá preklopiť do zdrojového kódu; ide o popis alebo predlohu riešenia. Návrhové vzory predstavujú formalizované best practices, ktoré programátor môže použiť pri riešení bežných problémov pri návrhu softvéru.
> [name=Wikipédia] [color=#0047AB]

> **Príklady** návrhových vzorov: _factory, adapter, iterator, builder, decorator, singleton, visitor,_ ...
> [color=purple]

### Dependency Injection (DI)

Povedzme, že máme triedu `Client`, ktorá pre svoju činnosť potrebuje funkcionalitu triedy `ServiceImpl`.

```java=
public class Client {
    // specific class dependency here
    private ServiceImpl service;
    
    public Client() {
        // Client is responsible for instantiating ServiceImpl
        this.service = new ServiceImpl();
    }
}
```

Takto previazané triedy sú **tightly coupled**. Ak by trebalo upraviť triedu `ServiceImpl`, bolo by nutné upraviť aj triedu `Client`, čo nie je ideálne.

:dart: Chceme dosiahnuť **loose coupling**[^coupling] medzi triedami/komponentami, tj. ich čo najväčšiu nezávislosť či nepreviazanosť.

> :bulb: **Dependency inversion principle** (DIP) odporúča používať **abstraktné závislosti** (rozhrania) namiesto konkrétnych (špecifických implementácií)[^dependency-inv].
> [color=#0047AB]

> :bulb: **Inversion of control principle** (IoC) presúva zodpovednosť za vytvorenie a previazanie objektov z aplikácie na framework.
> [color=#0047AB]
>
> - IoC sa používa na zvýšenie modularity a rozšíriteľnosti programu.
> - Príklad IoC frameworku: **`Spring`** (Java), **`Spring.NET`** (C#)

[^dependency-inv]: _"Depend upon abstractions, [not] concretions."_

[^coupling]:
    > _"Coupling refers to the degree of direct knowledge that one component has of another."_
    
    > _"In computing and systems design a loosely coupled system is one in which each of its components has, or makes use of, little or no knowledge of the definitions of other separate components."_

:::info
:bulb: **Dependency injection** (DI) je spôsob, ako **IoC** naimplementovať.
:::
Podľa DIP, IoC a rôznych druhov DI[^interface-injection] by trieda `Client` vyzerala nasledovne (`@Inject` je v Jave direktíva pre IoC framework):

```java=
// constructor injection
public class Client {
    /* service can be final as the class
     * is fully initialized upon instantiation
     * through the constructor
     */
    private final Service service;
    
    @Inject
    public Client(Service service) {
        this.service = service;
    }
}
```

```java=
// field injection
public class Client {
    @Inject
    private Service service;
}
```

```java=
// setter injection
public class Client {
    /* service is not final as the setter
     * method is used after instantiation
     */
    private Service service;
    
    @Inject
    public void setService(Service service) {
        this.service = service;
    }
}
```

[^interface-injection]: Okrem uvedených existuje ešte tzv. _interface injection_.

### Data Access Object (DAO)

:::info
:bulb: Návrhový vzor, ktorý **oddeľuje** low-level špecifiká prístupu k dátam (napr. využitia relačnej databázy) od high-level metód (logiky aplikácie).
:::
- Súčasťou vzoru sú zvyčajne tri triedy:
  - **rozhranie** (DAO interface), ktoré definuje poskytované metódy prístupu k dátam -- CRUD[^crud] operácie,
  - **konkrétna trieda**, ktorá implementuje rozhranie pre prístup ku konkrétnemu zdroju dát,
  - **entitná trieda**, ktorá definuje konkrétny dátový model (atribúty a ich typy).
    - Tiež tzv. _model object_ alebo _value object_.
    - Jej inštancie uchovávajú konkrétne údaje.

![DAO pattern example](https://www.tutorialspoint.com/design_pattern/images/dao_pattern_uml_diagram.jpg "DAO pattern example")

 :::success
:ok_hand: Výhoda -- **princíp oddelenia zodpovednosti** (_separation of concerns principle_): program je rozdelený na časti, ktorých funkcionalita (zodpovenosti) sa neprekrývajú.
- Programátor môže implementovať logiku aplikácie bez toho, aby vedel ako funguje prístup k dátam.
- Spôsob ukladania dát sa dá jednoducho zmeniť bez toho, aby bolo treba upravovať vyššiu logiku programu (za predpokladu, že pôvodné rozhranie zostane zachované).
:::
:::danger
:no_entry_sign: Nevýhoda -- **opakujúci sa kód** (_boilerplate code_) pre každú entitu, možno vyriešiť dedením všeobecnej implementácie.
:no_entry_sign: Nevýhoda -- aplikácia môže vďaka využívaniu metód poskytovaných cez DAO pristupovať k dátam **neefektívne** (viď napr. [problém n+1](#Problém-“n1”)).
:::

> [color=#0047AB]
> #### Problém "n+1"
> Majme entitu `článok` a k nej entitu `komentár` vo vzťahu many-to-one (článok môže mať viacero komentárov; komentár patrí k práve jednému článku).
> Povedzme, že v aplikácii najprv získame zoznam všetkých komentárov (jeden dotaz). Potom pre každý komentár cez `for` cyklus dohľadáme napr. názov odpovedajúceho článku. ($n$ dotazov). Takto použijeme (veľmi neefektívne) $n+1$ dotazov na operáciu, pre ktorú by stačil jeden dotaz obsahujúci join medzi entitami.

[^crud]: **C**reate **R**ead **U**pdate **D**elete

#### Zdroje
- https://www.tutorialspoint.com/design_pattern/data_access_object_pattern.htm
- https://en.wikipedia.org/wiki/Data_access_object
- https://vladmihalcea.com/n-plus-1-query-problem/

### Fasáda (_facade_)

:::info
:bulb: Fasáda je štruktúrový návrhový vzor, ktorý **poskytuje zjednodušené rozhranie** pre knižnicu, framework, alebo inú komplikovanú sadu tried.
:::

![](https://upload.wikimedia.org/wikipedia/en/5/57/Example_of_Facade_design_pattern_in_UML.png "Facade pattern")

> The facade lets the clients interact with the madness!
> [name=YouTube comment section]

Klienti (resp. iné systémy/podsystémy) by mali s daným podsystémom komunikovať výhradne cez jeho fasádu (ak im zjednodušené rozhranie postačuje). Prípadné zmeny v implementácii systému sa takto klientov nemusia vôbec dotknúť.

> **Príklad** zo života: pri telefonických objednávkach predstavuje operátor fasádu a sprístupňuje tak možnosti obchodu.
> [color=purple]


### Data Transfer Object (DTO)

- Tiež tzv. _value object_.
- Používa sa výhradne ako **dátová štruktúra** v prípadoch, kedy treba v jednom celku preniesť údaje napr. medzi klientom a serverom (zapuzdrenie dát).
- Je **serializovateľný** (viď doplňujúcu sekciu o [serializácii](#Serializácia)).
- Neobsahuje **žiadnu logiku** a k atribútom má definované gettery a settery, prípadne metódy potrebné pre serializáciu.
- Môže obsahovať **atribúty viacerých entít** (agregácia dát) -- cieľom je preniesť všetky potrebné dáta v jednom objekte.
- Objekt je pre klienta **read-only**; ak je potrebná zmena, klient si vytvorí nový DTO s aktualizovanými atribútmi a pošle ho späť na server.

Príklad[^userDTO] DTO v Jave (`equals()` a `hashCode()` sú pre krátkosť vynechané):
```java=
public class UserDTO {
    private Long id;
    private String passwordHash;
    private String email;
    private String givenName;
    private String surname;
    private Date joinedDate;

    public UserDTO() {
    }
    
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getPasswordHash() {
        return passwordHash;
    }

    public void setPasswordHash(String passwordHash) {
        this.passwordHash = passwordHash;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }


    public String getGivenName() {
        return givenName;
    }


    public void setGivenName(String givenName) {
        this.givenName = givenName;
    }


    public String getSurname() {
        return surname;
    }


    public void setSurname(String surname) {
        this.surname = surname;
    }

    public Date getJoinedDate() {
        return joinedDate;
    }

    public void setJoinedDate(Date joinedDate) {
        this.joinedDate = joinedDate;
    }

    @Override
    public String toString() {
        return "UserDTO{" +
                "id=" + id +
                ", passwordHash='" + passwordHash + '\'' +
                ", email='" + email + '\'' +
                ", givenName='" + givenName + '\'' +
                ", surname='" + surname + '\'' +
                ", phone='" + phone + '\'' +
                ", address='" + address + '\'' +
                ", joinedDate=" + joinedDate +
                '}';
    }
}
```

Zjednodušený príklad použitia DTO v klient-server aplikácii: server získa údaje z databázy, naplní nimi vhodný DTO a pošle ho klientovi.

```sequence
Client->Server: request
Server->Database: query
Database->Server: response
Note right of Server: Server aggregates response data into a new DTO
Server->Client: DTO
```

#### Serializácia
**Serializácia** je konverzia objektu do formátu, ktorý sa dá uložiť (do súboru, bufferu, ...) alebo preniesť (napr. cez sieť), tak, aby ho bolo možné neskôr znovu vytvoriť so zachovaním pôvodného stavu objektu. Opačná operácia sa nazýva **deserializácia**. Serializovať sa dá napr. do JSONu, prípadne do XML alebo ľubovoľného vlastného formátu (najčastejšie string, prípadne iný byte stream).

Podobnú operáciu popisuje pojem **marshalling**. Rozdiel medzi serializáciou a marshallingom podľa Javy:
> _To "marshal" an object means to record its state and codebase(s)[^codebase] in such a way that when the marshalled object is "unmarshalled", a copy of the original object is obtained, possibly by automatically loading the class definitions of the object. You can marshal any object that is serializable or remote. Marshalling is like serialization, except marshalling also records codebases. Marshalling is different from serialization in that marshalling treats remote objects specially. A [...] serializable object stored as a (marshalled object) represents the object itself, while [...] a remote object stored as a (marshalled object) represents a "pointer" to the object._
> [name=RFC 2713]

#### Zdroje
- https://www.tutorialspoint.com/design_pattern/transfer_object_pattern.htm
- https://stackabuse.com/data-transfer-object-pattern-in-java-implementation-and-mapping
- [RFC 2713](https://datatracker.ietf.org/doc/html/rfc2713)
- https://refactoring.guru/design-patterns/facade

[^userDTO]: Prevzaté a upravené zo [vzorového projektu PA165](https://github.com/fi-muni/PA165/blob/master/eshop-api/src/main/java/cz/fi/muni/pa165/dto/UserDTO.java)

[^codebase]: Pod pojmom _codebase_ sa v kontexte RFC 2713 myslí miesto (URL), na ktorom je uložená definícia danej triedy.
