Objektový návrh a asociace

stepik

Objektový návrh a asociace
« kdy: 15. 03. 2013, 07:30:47 »
ahoj četl jsem si nějaké články o závislosti jednotlivých tříd 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...
« Poslední změna: 15. 03. 2013, 08:00:49 od Petr Krčmář »


fgsadafd

Re:Objektový návrh a asociace
« Odpověď #1 kdy: 15. 03. 2013, 08:48:28 »
ahoj četl jsem si nějaké články o závislosti jednotlivých tříd 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.

stepik

Re:Objektový návrh a asociace
« Odpověď #2 kdy: 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 ??

Rax

Re:Objektový návrh a asociace
« Odpověď #3 kdy: 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š.

Natix

Re:Objektový návrh a asociace
« Odpověď #4 kdy: 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.


Rax

Re:Objektový návrh a asociace
« Odpověď #5 kdy: 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

Natix

Re:Objektový návrh a asociace
« Odpověď #6 kdy: 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.

Rax

Re:Objektový návrh a asociace
« Odpověď #7 kdy: 15. 03. 2013, 22:47:09 »
O jalové teoretické konstrukty založené na immutable nemám zájem.

Natix

Re:Objektový návrh a asociace
« Odpověď #8 kdy: 15. 03. 2013, 23:24:04 »
O jalové teoretické konstrukty založené na immutable nemám zájem.

Okay  ;D

Logik

  • *****
  • 1 022
    • Zobrazit profil
    • E-mail
Re:Objektový návrh a asociace
« Odpověď #9 kdy: 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 ....).

Rax

Re:Objektový návrh a asociace
« Odpověď #10 kdy: 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.