Abstrakce u OOP

Abstrakce u OOP
« kdy: 10. 06. 2020, 17:21:09 »
Zdravím, jaké výhody přináší abstrakce u OOP? Tedy abstrakce pomocí interfaců a abstraktních tříd? Jak bych to měl třeba vysvětlit u přijímacího pohovoru?


alex6bbc

  • *****
  • 1 432
    • Zobrazit profil
    • E-mail
Re:Abstrakce u OOP
« Odpověď #1 kdy: 10. 06. 2020, 17:38:59 »
ze jsou promenne i metody pekne pospolu obalene jednim objektem/tridou, ktera ucelene reprezentuje nejakou entitu.

a ze pak lze vytvaret hierarchii potomku a usetrit si tak psani kodu.

Re:Abstrakce u OOP
« Odpověď #2 kdy: 10. 06. 2020, 17:54:41 »
Pokud budete mít například službu, která posílá notifikace, můžete mít v  interface metodu send(), která notifikaci pošle. Při běhu programu si pak budete moci vybrat, zda chcete posílat notifikaci SMSkou neb mailem - podle toho program zvolí konkrétní implementaci posílání notifikací SMSkou nebo mailem. Kód volající send přitom může zůstat beze změny - vždy se zavolá metoda send daného interface. Navíc můžete nové implementace přidávat později a v programu samotném nemusíte nic měnit. Takto můžete přidávat moduly i k programu, ke kterému nemáte zdrojové kódy (hodí se pro systém pluginů).

Pseudokód - odeslání SMS zprávy za použití interface Notifier:

Kód: [Vybrat]
// zpráva k odeslání:
Message m = new Message("Ahoj");
// budeme odesílat Notifierem, nyní konkrétně SMS Notifierem:
Notifier n = new SmsNotifier();
// odešleme
n->send(m);


Kód: [Vybrat]
// uživatel přihlášený v programu si může sám volit zasílání zpráv SMS nebo mailem, volbu má uloženou v preferencích svého profilu

// získám aktuálního uživatele
User u = User.getById(...);
// zpráva k odeslání:
Message m = new Message();
// načtení Notifiera kterého si uživatel v preferencích svého profilu zvolil:
Notifier n = u.getPreferences().getNotifier()
// nevíme, jakého Notifiera si uživatel  zvolil, přesto bude kód fungovat:
n->send(m);

Další příklady: Úložiště může využívat uložení do databáze, do souborů nebo do cloudu - kam se data ve skutečnosti uloží záleží na výběru konkrétní implementace.
« Poslední změna: 10. 06. 2020, 17:57:04 od Ondrej Nemecek »

Idris

  • *****
  • 2 286
    • Zobrazit profil
    • E-mail
Re:Abstrakce u OOP
« Odpověď #3 kdy: 10. 06. 2020, 18:11:41 »
a ze pak lze vytvaret hierarchii potomku a usetrit si tak psani kodu.
Code reuse dědičností se považuje za antipattern.

Idris

  • *****
  • 2 286
    • Zobrazit profil
    • E-mail
Re:Abstrakce u OOP
« Odpověď #4 kdy: 10. 06. 2020, 18:13:48 »
Je to jako každá jiná abstrakce, zjednodušuje návrh použitím vhodného modelu. Klíčové slovo je polymorfismus (rozhraní umožňuje typovat objekty dynamicky při zachování typové kontroly v době překladu).


AgentK

  • ***
  • 129
  • Evolve or die!
    • Zobrazit profil
    • E-mail
Re:Abstrakce u OOP
« Odpověď #5 kdy: 10. 06. 2020, 19:07:26 »
a ze pak lze vytvaret hierarchii potomku a usetrit si tak psani kodu.
Code reuse dědičností se považuje za antipattern.
Rozhodně. Tohle bych zrovna doporučil neříkat. :-)

alex6bbc

  • *****
  • 1 432
    • Zobrazit profil
    • E-mail
Re:Abstrakce u OOP
« Odpověď #6 kdy: 10. 06. 2020, 19:13:03 »
a ze pak lze vytvaret hierarchii potomku a usetrit si tak psani kodu.
Code reuse dědičností se považuje za antipattern.

a to jako proc?!  pokud mam kod, ktery lze napsat uz v rodici a neni zavisly na specializaci potomka, tak patri do rodice.

alex6bbc

  • *****
  • 1 432
    • Zobrazit profil
    • E-mail
Re:Abstrakce u OOP
« Odpověď #7 kdy: 10. 06. 2020, 19:16:14 »
a ze pak lze vytvaret hierarchii potomku a usetrit si tak psani kodu.
Code reuse dědičností se považuje za antipattern.

kdyz se spravne rozhodne zda se ma pouzit dedeni (IS it) nebo kompozice (HAS it), tak pak je dedicnost nebo naopak kompozice spravne. takze tvrdit, ze to je antipattern a smytec je antipattern.

ze muze dojit k vytvoreni "god object" jeste nesnizuje inheritanci a metody v rodici jako celek.
« Poslední změna: 10. 06. 2020, 19:20:48 od alex6bbc »

Kit

  • *****
  • 704
    • Zobrazit profil
    • E-mail
Re:Abstrakce u OOP
« Odpověď #8 kdy: 10. 06. 2020, 19:32:41 »
a ze pak lze vytvaret hierarchii potomku a usetrit si tak psani kodu.
Code reuse dědičností se považuje za antipattern.
a to jako proc?!  pokud mam kod, ktery lze napsat uz v rodici a neni zavisly na specializaci potomka, tak patri do rodice.

Code reuse nesmí být jediným důvodem pro použití dědičnosti. Potomek musí být specializací předka.

BoneFlute

  • *****
  • 1 981
    • Zobrazit profil
Re:Abstrakce u OOP
« Odpověď #9 kdy: 10. 06. 2020, 20:05:13 »
a ze pak lze vytvaret hierarchii potomku a usetrit si tak psani kodu.
Code reuse dědičností se považuje za antipattern.

kdyz se spravne rozhodne zda se ma pouzit dedeni (IS it) nebo kompozice (HAS it), tak pak je dedicnost nebo naopak kompozice spravne. takze tvrdit, ze to je antipattern a smytec je antipattern.

Protože tohle ty neříkáš, že jo. Ty říkáš, že
a ze pak lze vytvaret hierarchii potomku a usetrit si tak psani kodu.
Code reuse dědičností se považuje za antipattern.

a to jako proc?!  pokud mam kod, ktery lze napsat uz v rodici a neni zavisly na specializaci potomka, tak patri do rodice.
Z čehož jsme pochopily, že se snažíš o reusable kódu pomocí dědičnosti. Což je antipattern a šmitec.

To, že nějaký kód patří do předka, protože tam patří, o tom už se dá bavit.

Re:Abstrakce u OOP
« Odpověď #10 kdy: 10. 06. 2020, 20:31:29 »
Z čehož jsme pochopily, že se snažíš o reusable kódu pomocí dědičnosti. Což je antipattern a šmitec.

proč, podle koho? Jaká to má negativa?

To, že nějaký kód patří do předka, protože tam patří, o tom už se dá bavit.

jak poznám, že tam patří?

BoneFlute

  • *****
  • 1 981
    • Zobrazit profil
Re:Abstrakce u OOP
« Odpověď #11 kdy: 10. 06. 2020, 20:45:38 »
Z čehož jsme pochopily, že se snažíš o reusable kódu pomocí dědičnosti. Což je antipattern a šmitec.

proč, podle koho? Jaká to má negativa?

Kromě ideového sporu, tak praxe mi ukazuje:

Heslovitě:
- prosakování implementace (předek rozumí potomkovi)
- neočekávané předpoklady (předek očekává, že potomek bude dělat něco, a ten netuší co)
- předek má podivné chování (protože to používá jeden potomek)
- voláme metodu, jejíž implementace je rozprsklá přes velké množství tříd
- neizolovatelný kód (voláme metodu, která vytváří objekt, který volá metodu, která vytváří objekt, a ten volá metodu - tu na začátku)

Jako obecně a subjektivně: když přijdu ke kódu, kde se používá dědičnost na reusable kódu, tak vím co mě čeká. Nepomáhá to, je to nepřehledné, nevím co se děje, nedá se to pořádně refaktorovat, testovat, nedá se s tím nic, než tiše trpět.

To, že nějaký kód patří do předka, protože tam patří, o tom už se dá bavit.

jak poznám, že tam patří?
Tak existuje klasické pravidlo, zda objekt IS nebo objekt HAS.
Případně jednodužší, pokud nemusíš, tak to nedělej.

Já jsem se naučil používat interface, abstraktním třídám a dědičnosti se spíše vyhýbám, a dost se mi to osvědčilo.

Re:Abstrakce u OOP
« Odpověď #12 kdy: 10. 06. 2020, 20:52:15 »
jak poznám, že tam patří?
Veřejnou dědičností se modelují vztahy is-a. O každém potomkovi by se mělo dát říct, že je zároveň předkem. Navíc to není podmínka postačující, ale jen nutná.
Takže do předka patří jen taková logika, kterou mají všichni potomci. Pokud dává smysl jen pro některé potomky, pak předek nejspíš není to pravé místo.

Příklad funkčnosti, která mi dává v předkovi smysl, je kontrola vstupů, návratových hodnot a invariantů.

Samozřejmě jako všechno u návrhu SW je to důsledné doporučení a nedá se tupě aplikovat vždycky a bez přemýšlení.

BoneFlute

  • *****
  • 1 981
    • Zobrazit profil
Re:Abstrakce u OOP
« Odpověď #13 kdy: 10. 06. 2020, 20:52:26 »
Zdravím, jaké výhody přináší abstrakce u OOP? Tedy abstrakce pomocí interfaců a abstraktních tříd? Jak bych to měl třeba vysvětlit u přijímacího pohovoru?

Možná by se dalo říct, že abstrakce umožňuje zobecnit problém s tím, že rozdělíme fázi pohled na celkový kontext a pohled na konkrétní implementaci/detaily. Čímž si jednak zjednodušíme život, protože nám to hlava pobere, a druhak umožníme, abychom mohli později vytvářet implementace, se kterými jsme na začátku ani nepočítali.

Interface s OOP imho nesouvisí. Ale Interface souvisí s tím, že dokážem vynutit, aby tam bylo nějaké rozhraní, které můžeme používat (pohled z celku), za kterým jsou schované detaily (pohled zevnitř).

Lépe než mnou to bylo vysvětleno v jednom rozhovoru na root.cz-u, ale nemohu ho najít.

BoneFlute

  • *****
  • 1 981
    • Zobrazit profil
Re:Abstrakce u OOP
« Odpověď #14 kdy: 10. 06. 2020, 20:55:15 »
jak poznám, že tam patří?
Veřejnou dědičností se modelují vztahy is-a. O každém potomkovi by se mělo dát říct, že je zároveň předkem. Navíc to není podmínka postačující, ale jen nutná.
Takže do předka patří jen taková logika, kterou mají všichni potomci. Pokud dává smysl jen pro některé potomky, pak předek nejspíš není to pravé místo.

Příklad funkčnosti, která mi dává v předkovi smysl, je kontrola vstupů, návratových hodnot a invariantů.

Samozřejmě jako všechno u návrhu SW je to důsledné doporučení a nedá se tupě aplikovat vždycky a bez přemýšlení.

V poslední době se v některých jazycích rozšířili traity/mixiny, které jsou určeny právě na to reusable kódu. Protože sice do objektu přidávají logiku, kterou chceme, ale nepřidávají, že potomek JE předek.