Java týden Body zdarma
Využij podzimních slev a získej od nás až 40 % bodů zdarma! Více zde
Pouze tento týden sleva až 80 % na Java e-learning!

Facade (fasáda)

Unicorn College Tento obsah je dostupný zdarma v rámci projektu IT lidem.
Vydávání, hosting a aktualizace umožňují jeho sponzoři.

Návrhový vzor Facade (fasáda) se používá k vytvoření jednotného rozhraní pro celou logickou skupinu tříd, které se tak sdruží do subsystému.

Motivace

Mnohdy v naší aplikaci pracujeme s několika rozhraními různých tříd. To může být často nepřehledné, zejména pokud jsou rozhraní tříd složitá. Pokud spolu třídy logicky souvisí, můžeme je sdružit do subsystému pomocí fasády (Facade). Získáme tak jednotné rozhraní pro funkcionalitu, kterou nám subsystém poskytuje.

Vzor

Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

Fasáda (Facade) je poměrně jednoduchý vzor, který se skládá z jedné třídy, která fasádu tvoří. Ta je napojena na další třídy, se kterými pracuje. Zvenku je však vidět jen fasáda (od toho název), a ta zastupuje rozhraní pro celý subsystém. Celá složitá struktura tříd je v pozadí.

Návrhový vzor Facade/fasáda

Sníží se tím počet tříd, se kterými komunikujeme. Subsystém se lépe používá i testuje. Jedná se tedy opět o prostředníka a je tu určitá podobnost se vzorem Adapter (Wrapper) . My ovšem obalujeme rovnou několik tříd do jednoho logického subsystému.

Příkladem by mohla být fasáda pro práci s PC na úrovni hardwaru. Sdružovala by třídu co umožňuje počítač uspat, restartovat nebo vypnout. Dále třídu co by upravovala jas monitoru a další, co by četla teploty procesoru a disku. Fasáda by zastřešila všechny metody do jednoho rozhraní. Mohla by obsahovat i jen vybrané metody pro náš účel.

Výhodou vzoru je také vyřešení závislostí jednotlivých komponent v subsystému. Pokud mezi nimi předáváme nějakou instanci, řeší se to uvnitř fasády.


 

 

Článek pro vás napsal David Čápka
Avatar
Jak se ti líbí článek?
9 hlasů
Autor pracuje jako softwarový architekt a pedagog na projektu ITnetwork.cz (a jeho zahraničních verzích). Velmi si váží svobody podnikání v naší zemi a věří, že když se člověk neštítí práce, tak dokáže úplně cokoli.
Unicorn College Autor sítě se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.
Předchozí článek
Adapter (wrapper)
Všechny články v sekci
GOF - Vzory struktury
Aktivity (2)

 

 

Komentáře

Avatar
info
Člen
Avatar
info:15.2.2016 11:09

Ako je to z rýchlosťou pri tomto návrhovom vzore? PHP modul(parsing engine) načíta celý subsystém , teda všetky triedy , alebo len tie triedy ktorých metódy a atribúty sú volané.

 
Odpovědět 15.2.2016 11:09
Avatar
Patrik Pastor:15. června 21:01

Jak se toto lisi od klasickeho interface? Tady jste vpodstate krasne popsali co dela interface, ale to bylo v kurzu o objektovem programovani. Zadnou pridanou hodnotu tento clanek nema.

 
Odpovědět 15. června 21:01
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na Patrik Pastor
Martin Dráb:16. června 1:01

Jak se toto lisi od klasickeho interface? Tady jste vpodstate krasne popsali co dela interface, ale to bylo v kurzu o objektovem programovani. Zadnou pridanou hodnotu tento clanek nema.

Cílem návrhových vzorů (včetně fasády) je nabídnout rozumná řešení pro různé problémy menšího rozsahu. Ač se obvykle ukazují na třídách, rozhraních a jiných konceptech z OOP, nejsou vázány ani programovacím jazykem ani paradigmatu (OOP). Jedná se zkrátka o návody ve stylu "když máš problém X, měl bys jej řešit právě způsobem Y".

Interface je koncept z OOP světa, takže se nachází na nižší úrovni abstrakce. Může být použit k implementaci některých návrhových vzorů, ale nezdá se mi, že by zrovna pokrýval hlavní myšlenku fasády (schovat skupinu tříd a závislosti mezi nimi před okolním světem a ubrat mu tím plno starostí).

Ako je to z rýchlosťou pri tomto návrhovom vzore? PHP modul(parsing engine) načíta celý subsystém , teda všetky triedy , alebo len tie triedy ktorých metódy a atribúty sú volané.

Tohle je na třídě/kódu reprezentující/m fasádu, a tedy na programátorovi. Návrhové vzory nedávají vyčerpávající odpověď na problémy, pro jejichž řešení jsou určeny – obvykle existuje více možností jejich implementace a je třeba se rozhodnout podle konkrétní instance problému. Když se třeba podíváš původní knížky o návrhových vzorech od Gang of Four, zjistíš, že za popisem myšlenky návrhového vzoru vždy následuje celkem dlouhá diskuze o tom, jak jej implementovat.

Editováno 16. června 1:02
Odpovědět 16. června 1:01
2 + 2 = 5 for extremely large values of 2
Avatar
Odpovídá na Martin Dráb
Patrik Pastor:16. června 9:09

Napsal jsi: "schovat skupinu tříd a závislosti mezi nimi před okolním světem a ubrat mu tím plno starostí" , ale toto presne interface dela. Je to "kostra" pro implementaci dalsich (jez by z tohoto interface dedily) trid, tedy v teto kostre mohou byt ony zavislosti, ktere ubyvaji na starosti. Jako navrhovy vzor to chapu, ale stale se zastavam toho ze implementace fasady je prosty interface (tak jak to programator skutecne zavede, fasadu). Jinak sem nepochopil, napsal jsi ze OOP snizuje abstrakci.. Nezvysuje ji spis nahodou?(kdyz muzes dedit, apod)/.

 
Odpovědět 16. června 9:09
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na Patrik Pastor
Martin Dráb:16. června 10:54

OOP snizuje abstrakci.. Nezvysuje ji spis nahodou?

Bylo myšleno ve srovnání s návrhovými vzory, které považuji za obecnější (k jejich použití nepotřebuješ OOP).

ale toto presne interface dela

Ta skupina tříd, kterou fasáda schovává před okolním světem, nemusí dodržovat žádný interface, což je právě pro okolní svět obtížné. Fasáda, dalo by se říci, může pomoci v tom, žepro přístup ke třídám ten interface sjednocuje.


Jako příklad z neOOP světa si třeba můžeme vzít zsíkávání systémových informací (a třeba i informací týkající se aktuálního vytížení systému) na Windows. Můžeš k tomu využít sadu všelijakých funkcí s naprosto nejednotným rozhraním. Pokud chceš jednotné rozhraní pro přístup k těmto informacím, můžeš využít

  • pseudoklíč registru HKEY_PERFORMAN­CE_DATA,
  • knihovnu Performance Data Helper,
  • pravděpodobně i WMI.

Tyhle tři fasády (druhý je adaptérem nad prvním) ti poskytují jednotné rozhraní k něčemu, co bys mohl nazvat skupinou tříd (ve skutečnosti je vše implenentováno v C, takže se jedná o skupinu různorodých funkcí).

Odpovědět 16. června 10:54
2 + 2 = 5 for extremely large values of 2
Avatar
Odpovídá na Martin Dráb
Patrik Pastor:16. června 11:50

pochopil jsem to tak, ze fasada je jeste jakoby "nad interfacem"? Tedy co to je (jak vypada implementace)? Je to classa? Co muze byt na interfacem, ktery je "kostrou" pro dalsi implementace? Kdyz rikas ze fasada SJEDNOCUJE interface (ale nemel by sjednocoval prave interface classy)?

 
Odpovědět 16. června 11:50
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
Odpovídá na Patrik Pastor
Michal Šmahel:16. června 13:00

Ahoj, koukám, že tomu celkově moc nerozumíš. Pokusím se ti to vysvětlit, abys to v budoucnu špatně neimplementoval. On je totiž rozdíl mezi rozhraním a fasádou poměrně značný.

Rozhraní (interface) - coby prvek OOP
Rozhraní se dá využít na více věcí, ale nyní se zaměřím pouze na tvorbu abstrakce. V tomto případě (jak již název napovídá) je tvořeno rozhraní (přes které lze k něčemu přistupovat) pro komunikaci s dalšími třídami. Rozhraní (OOP) nařizuje třídám, které ho implementují, povinnost vlastnit určitou veřejnou funkcionalitu. Z toho vyplívá, že se všechny těmito třídami mohu komunikovat stejně, a dostat stejný formát (datový typ) výsledku. Každá tato třída si však může data získávat, jak chce. Také může vracet jiné výsledky. Důležité je, že dodržuje stejný formát vstupu a výstupu. Rozhraní (OOP) tedy umožňuje k několika třídám přistupovat stejným způsobem (skrz jejich společné rozhraní).

Fasáda (Facade)
Fasáda narozdíl od rozhraní (OOP) není prvkem OOP, ani ho nemusí dodržovat. Může fungovat klidně s funkcemi a jejich soubory. Jedná se totiž o návrhový vzor (toto již konstatoval Martin Dráb). Já se omezím pouze na použití v OOP. Narozdíl od rozhraní (OOP) poskytuje rozhraní (přístup) k několika třídám, které spolu tvoří určitý subsystém (celek tříd, které mezi sebou spolupracují a poskytují tak nějakou komplexní funkcionalitu). Fasádu tvoří jedna nebo více tříd, které poskytují základní funkcionalitu (rozhraní ve smyslu přístupu) totoho subsystému. To ale však neznamená, že je jedná o jedno nebo více rozhraní (OOP), ale o třídu, která obsahuje několik metod z různých tříd subsystému a sjednocuje je v menší jednodušší celek. Tato třída (fasáda) má závislost na všech třídách subsystému, s nimiž přímo spolupracuje. V případě použití fasády v kódu dojde k vybrání správné závislosti a zavolání správné metody, která jí patří. Třídy subsystému však o fasádě neví, narozdíl od rozhraní (OOP), kdy musí dodržovat jeho zásady.

Abych to nějak shrnul. Rozhraní (OOP) zastřešuje několik tříd stejně jako fasáda. Rozdíl je však v tom, že fasáda třídám, které zastupuje, nic nenařizuje, ale řídí se jejich strukturou. Rozhraní (OOP) poté nastavuje, jak se budou jemu podřazené třídy chovat, aby s nimi bylo možné vždy pracovat jako s jednou třídou (daným rozhraním ve smyslu OOP).

Snad jsem ti nezamotal hlavu ještě více. Pokud ano, ještě napiš, pokusím se to ukázat na příkladech.

Odpovědět  +2 16. června 13:00
Nejdůležitější je motivace, ovšem musí být doprovázena činy.
Avatar
Odpovídá na Michal Šmahel
Patrik Pastor:16. června 14:01

precetl jsem si to vickrat a trochu mi to zacalo davat smysl. Akorat bych mel pouze jednu poznamku k predposlednimu odstavci (kde shrnujes vyznam obou):
Interface narizuje metody, to mas pravdu a fasada dava rozhrani (strukturu) to bych taky pochopil. Jenom me napada, pokud tedy jde o to, aby to nebylo "povinna implementace", tak, jak to interface (oop) ma, nestacilo by potom pouzit Abstraktni tridu? Nemohla by abstraktni trida nahradit fasadu (nebo jeji implementaci), protoze ta zadnou nucenou implementaci nema(narozdil od interface).

 
Odpovědět 16. června 14:01
Avatar
Martin Petrovaj
Překladatel
Avatar
Odpovídá na Patrik Pastor
Martin Petrovaj:16. června 15:06

Ďalší možný spôsob vysvetlenia (dosť zjednodušený a polopatistický):

Interface
Ak objekt implementuje nejaký interface, tak tento interface mu dáva povinnosť implementovať nejakú funkcionalitu - napr. metódu, ktorá berie vstup typu X a vracia výstup typu Y. Pri dodržaní interfacom stanovených pravidiel ho môže implementovať ktokoľvek a akokoľvek. Ak trieda implementuje interface, v podstate oznamuje zvyšku sveta "nemusíte sa starať o to, kto presne som, ale viem robiť toto a tamto".

Hlavný význam interfacov je v tom, že zvyšku programu obvykle stačí pracovať s objektom cez jeho rozhranie a nestarať sa o to, aká konkrétna trieda sa za tým rozhraním skrýva. Ak som zapisovač do textového súboru, je mi jedno, či mi príde na vstupe pole čísel alebo objekt Lietadlo, dôležité je, či implementujú nejaké mnou požadované rozhranie napr. s metódou Serialize.

Povedzme, že nejaký účtovný program počíta náklady firmy na jednotlivých zamestnancov. Na to logicky potrebuje poznať aj ich plat. Takže v metóde na to určenej si vyžiada parameter, ktorý implementuje rozhranie Pracovnik (alebo IPracovnik pre C# folks). Rozhranie obsahuje metódu decimal VratPlatZaPos­lednyMesiac(). Program na výpočet zamestnancov si ju len zavolá a má informácie, ktoré potrebuje. Pod tým rozhraním pritom mohli byť rôzne konkrétne triedy, ktoré si tú metódu implementovali inak. Napr. objekty triedy BeznyZamestnanec ju implementovali tak, že len vždy vrátili fixnú čiastku; objekty triedy PartTimeZamestnanec vrátili polovicu z fixnej čiastky, objekty triedy Externista mali vnútorné počítadlo hodín a vynásobili ním hourly rate, vynásobí to DPH atď. Ale zmieňovaný program o ničom z toho nemusí vedieť a nestará sa o to. Len komunikuje s rozhraním každého pracovníka a nestará sa o implementáciu pod ním.

Facade
Niekedy je požadovaná funkcionalita zložitá a na jej implementovanie potrebujeme použiť viac rôznych tried (ak nie sme prasáci a nepíšeme v roku 2019 40000-riadkové programy celé v static int Main()). Lenže kvôli prehľadnosti a udržateľnosti kódu nechceme, aby zvyšok programu / softvéru musel komunikovať so všetkými týmito triedami. Vytvoríme preto jednu, ktorá poskytuje už výsledné výstupy (tým, že vnútorne komunikuje s tými ostatnými triedami a prevoláva ich metódy), a táto jedna trieda predstavuje návrhový vzor fasáda. Jej účelom je poskytnúť abstrakciu nad zložitejším systémom a zjednodušiť prístup k nemu.

Napr. skôr zmienený účtovný program môže v nejakom dashboarde zobraziť používateľovi celkové náklady firmy (napr. pre jednoduché porovnanie so ziskami, whatever). Na to nestačí spočítať len náklady na mzdy, ale treba zarátať aj nájom priestorov, energie, materiál, infraštruktúru atď. O kalkuláciu mzdových nákladov sa stará trieda SalaryCalculator, metódu pre získanie nákladov na nájom a energie obsahuje OfficeManager, zakúpený materiál a jeho cenu treba vytiahnuť a spočítať z faktúr v databázi cez InvoiceRepository atď. Proste kopa práce cez X subsystémov.

Aby frontend a UI aplikácie nemuselo riešiť to, ako sa celkové náklady vlastne spočítajú a odkiaľ sa získavajú (podľa Single Responsibility Principle a Law of Demeter), tak vytvoríme jednu kompaktnú triedu, ktorá sa o toto všetko postará sama, napr. ExpensesCalculator. Frontend potom len zavolá jednu alebo dve metódy z tejto novej triedy a bude mať všetky informácie, ktoré pre ten dashboard potrebuje. Vďaka ExpensesCalculatoru nie je frontend nijako viazaný na kvadrilión ďalších tried z backendu, nevykonáva sám žiadne kalkulácie a ExpensesCalculator je implementáciou návrhového vzoru fasáda.

Oba tieto pojmy sú si významovo dosť podobné, ide hlavne o to rozlíšiť kontext. Interface sa týka OOP a vzťahuje sa na jednotlivé triedy, Facade je návrhový vzor, ktorý už rieši vzťahy medzi viacerými triedami v širšom kontexte.

Odpovědět  +2 16. června 15:06
if (this.motto == "") { throw new NotImplementedException(); }
Avatar
Odpovídá na Martin Petrovaj
Michal Šmahel:17. června 6:23

Díky za doplnění z praktické stránky věci. Já se to snažil držet v teoretické rovině, ale jak je vidět, praktické uplatnění často poví více než teorie.

Odpovědět 17. června 6:23
Nejdůležitější je motivace, ovšem musí být doprovázena činy.
Avatar
Odpovídá na Patrik Pastor
Michal Šmahel:17. června 6:38

Abstraktní třída pro samotnou fasádu není moc vhodná. Dala by se však použít v kombinaci s něčím jiným, ale to bych sem teď nepletl, reálná využitelnost tam bude mizivá. Důvodem nevhodnosti je to, že abstraktní třída funguje podobně jako rozhraní (OOP). Není možné z něho vytvořit instanci a dále ho používat coby běžnou závislost.

Použít by to šlo, pokud by bylo zapotřebí mít více rozhraní (přístupů) pro jednu fasádu. Například, pokud máš v programu několik zdrojů dat - databáze, import (např. nějaké archivní soubory). Na příkladu účetního systému by se to dalo aplikovat třeba takto: v databázi jsou ukládána data po nějakou dobu (např. 10 let) a poté jsou z nějakých důvodů archivována vyexportováním do archivních souborů. Pokud bys poté potřeboval udělat vzdálené srovnání (např. stavu před 30 lety), musel bys využít i archiv. Základní fasáda by byla implementována skrz abstraktní třídu, která by měla obecně chování. Jelikož se pracuje jinak s daty z databáze a jinak s archivními daty, je potřeba zhotovit dva potomky abstraktní třídy. Každý potomek poté bude konkrétní fasádou, z níž je možné vytvořit instanci (a tedy i závislost).

Jak je vidět, vždy to končí běžnou třídou - i v případě využití abstraktní třídy.

Odpovědět  +1 17. června 6:38
Nejdůležitější je motivace, ovšem musí být doprovázena činy.
Avatar
Patrik Pastor:17. června 7:51

dik vsem.

 
Odpovědět 17. června 7:51
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 12 zpráv z 12.