Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: stepik 15. 03. 2013, 07:30:47

Název: Objektový návrh a asociace
Přispěvatel: stepik 15. 03. 2013, 07:30:47
ahoj četl jsem si nějaké články o závislosti jednotlivých tříd (http://www.robertdresler.cz/search/label/Princip%20otev%C5%99enosti%20a%20uzav%C5%99enosti) pomocí Open-closed principu nicméně nevím jak mám tenhle princip uplatnit když jsou dvě třídy v asociace a nevím jestli se vůbec nějak uplatnit dá. Např. když mám třídu Kruh a v ní vlastnost Stred:Bod .. jediné co mě napadlo je že princip dodržím když budu pracovat jen s veřejným rozhraním vl. Stred a při úpravě třídy Bod budu toto rozhraní zachovávat...
Název: Re:Objektový návrh a asociace
Přispěvatel: fgsadafd 15. 03. 2013, 08:48:28
ahoj četl jsem si nějaké články o závislosti jednotlivých tříd (http://www.robertdresler.cz/search/label/Princip%20otev%C5%99enosti%20a%20uzav%C5%99enosti) pomocí Open-closed principu nicméně nevím jak mám tenhle princip uplatnit když jsou dvě třídy v asociace a nevím jestli se vůbec nějak uplatnit dá. Např. když mám třídu Kruh a v ní vlastnost Stred:Bod .. jediné co mě napadlo je že princip dodržím když budu pracovat jen s veřejným rozhraním vl. Stred a při úpravě třídy Bod budu toto rozhraní zachovávat...

http://en.wikipedia.org/wiki/Open/closed_principle

pokud mas uvnitr tridy Kruh pouzitou tridu Bod pro promennou stred, tak to rika, ze se nebudes hrabat uvnitr tridy Bod, ale pouzijes jen jeho verejne metody.

jiny priklad, mam miminko a to se pocurava. open-closed principle rika, ze nebudu menit vlastnosti minima, ale jenom jeho okoli, tj. ze mu dam plinku.
Název: Re:Objektový návrh a asociace
Přispěvatel: stepik 15. 03. 2013, 12:53:29
no ok napadlo mě ještě, že bych mohl definovat proměnnou s datovým typem rovným rozhraní a v jednotlivých metodách bych mu pak přiřazoval jednotlivé objekty.. používá se to takhle ??
Název: Re:Objektový návrh a asociace
Přispěvatel: Rax 15. 03. 2013, 15:08:58
Nevím jestli je to podle teorie správně, ale dělá se to takto:
Uděláš potomka Bodu StredKruznice, dovnitř si v konstruktoru předáš pointer na Kružnici a předefinuješ si nějaké metody které potřebuješ, které mimo tvojí nové funkce zavolají i původní metody Bodu. V kružnici si vytvoříš instanci StredKruznice a z Kružnice pak ven vystrčíš instanci StredKruznice.

Také je možné celou Kružnici dělat jako potomka Bodu, ale to asi není co potřebuješ.
Název: Re:Objektový návrh a asociace
Přispěvatel: Natix 15. 03. 2013, 15:50:58
Také je možné celou Kružnici dělat jako potomka Bodu, ale to asi není co potřebuješ.

To rozhodně není dobrý nápad, viz http://en.wikipedia.org/wiki/Circle-ellipse_problem

Celkově nevím, co vymýšlíte za složitosti:

Kód: [Vybrat]
interface Point {
  int x();
  int y();
}

interface Circle {
  int radius();
  Point centre();
}

class DefaultCircle implements Circle {
  private final int radius;
  private final Point centre;

  public DefaultCircle(int radius, Point centre) {
    this.point = point;
    this.centre = centre;
  }

  public int radius() {
    return radius;
  }

  public Point centre() {
    return centre;
  }
}

OCP je jenom o tom, že použitím abstraktních typů (ať už abstraktních tříd, interfaců, traitů nebo whatever) mám mezi objekty volné vazby jen přes jejich API (tzn. jejich veřejné metody), díky čemuž můžu vesele měnit implementaci (ať už jenom úpravou dané implementační třídy nebo záměnou za úplně jinou třídu implementující stejný interface), aniž bych musel překopávat klientské třídy (jiné třídy, které s danou třídou pracují). To ovšem má jednu podmínku a to, že API interfaců se nemůže měnit nekompatibilním způsobem (nemůžu smazat nebo upravit metodu). To je ta "closed for modification" část OCP.

Na druhou stranu, tahle abstrakce mi umožňuje dané interfacy vesele rozšiřovat, např. interface ColoredCircle extends Circle, který bude mít navíc třeba metodu vracející barvu kružnice. Takováhle rozšiřující změna nijak nerozbije klientský kód.
Název: Re:Objektový návrh a asociace
Přispěvatel: Rax 15. 03. 2013, 16:08:03
Takhle jak jsi to napsal je sice krásné, ale je to na*ovno, když bude třeba kružnici obarvit na červeno když se Y v Point nastaví záporné a analogicky na černo když je Y kladné.

Tvůj další postup bude že definuješ interface které implementuje Circle i Point a budeš psát desítky wrapperů pro metody každé takto adoptované třídy, jako u blbečků na dvorečku.

Tím vším už jsem si prošel a na teoretiky už se*u :o
Název: Re:Objektový návrh a asociace
Přispěvatel: Natix 15. 03. 2013, 20:49:12
Takhle jak jsi to napsal je sice krásné, ale je to na*ovno, když bude třeba kružnici obarvit na červeno když se Y v Point nastaví záporné a analogicky na černo když je Y kladné.

Tvůj další postup bude že definuješ interface které implementuje Circle i Point a budeš psát desítky wrapperů pro metody každé takto adoptované třídy, jako u blbečků na dvorečku.

Tím vším už jsem si prošel a na teoretiky už se*u :o

Implementovat Circle i Point v jedné třídě je podle mě nesmysl. Kružnice má střed, který je bodem, ale kružnice rozhodně bodem není. Teoreticky by se mohlo říct, že kružnice s nulovým poloměrem je bod, jenže to by pak platilo třeba i pro čtverec s nulovou stranou atd. což by vedlo k tomu, že bys ses ve chvíli, kdy bys chtěl nadefinovat equals relaci, se z toho zbláznil (čímž se dostáváme zase ke zmiňovanému problému kružnice a elipsy).

A protože jak Point, tak Circle výše, jsou jednoduché immutable datové struktury, tak nepotřebuji psát žádné wrappery ani montovat šílenosti typu, že střed potřebuje referenci na svou kružnici. Barva kružnice se tím pádem rozhodne jednou podmínkou v konstruktoru na základě předaného Pointu, nic víc netřeba.
Název: Re:Objektový návrh a asociace
Přispěvatel: Rax 15. 03. 2013, 22:47:09
O jalové teoretické konstrukty založené na immutable nemám zájem.
Název: Re:Objektový návrh a asociace
Přispěvatel: Natix 15. 03. 2013, 23:24:04
O jalové teoretické konstrukty založené na immutable nemám zájem.

Okay  ;D
Název: Re:Objektový návrh a asociace
Přispěvatel: Logik 16. 03. 2013, 00:31:19
Rax:
jo - a teď si představ, že nemáš jen kružnici ale N různých geometrických tvarů a pro každou jejich instanci budeš mít jiná pravidla pro obarvování. To pro každej typ parametru každého geometrického útvaru budeš definovat subclass z bodu???
Hodně rychle uvidíš, že Tvůj přístup je blbina a že ten "teoreticky správný" OOP přístup, tedy nechat bod bodem a když holt barva kružnice závisí na poloze bodu X, tak ji určovat "on demand" z aktuální polohy bodu je ve skutečnosti daleko jednodušší a zároveň blbuvzdornější.

PS: Druhá, opět OOP čistá metoda je umožnit bodu (nebo jeho podtřídě) informovat LIBOVOLNÉHO zájemce o změně své polohy. Ale subtypovat objekt jen kvůli agregaci třídy do jiné třídy je prasečina. Subtypovat kružnici z bodu je pak prasečina ještě větší (až budu potřebovat ještě čtverec a elipsu a pro všechny nějakého společného předka, protože to jsou oba dva 2D objekty, které určitě budou mít mnoho společného, tak ....).
Název: Re:Objektový návrh a asociace
Přispěvatel: Rax 16. 03. 2013, 01:19:20
To pro každej typ parametru každého geometrického útvaru budeš definovat subclass z bodu???

To by mi vrozená lenost neumožnila :-) Kdyby jich bylo N, místo pointeru na instanci si obecně předám callback nebo delegáta, ale alespoň jednoho potomka Bodu bych si udělal.

určovat "on demand" z aktuální polohy bodu.

Přepočítávat to zas a znovu mě nepřipadá dostatečně zajímavé řešení.

Subtypovat kružnici z bodu je pak prasečina ještě větší

S tím by se dalo souhlasit, kdyby nebyla řeč jenom o bodu a kružnici.
Je jasné, že 2D objekty se dělají jako potomci virtuálního opsaného obdélníku se stranami rovnoběžnými se souřadnými osami s vlastnostmi třeba x,y,w,h.