Tak já to zkusím - úplný základ.
1. Objekty používám k modelování procesů v reálném světě.
2. Objekt je minimální sada dat, na kterých můžu provádět společné operace.
3. Jeden z mých nejdůležitějších úkolů je od sebe oddělit rozhraní, pomocí kterého objekt komunikuje s okolím, a způsob, jak to konkrétně řeší; definovat, co je veřejné (rozhraní) a co soukromé (implementace). Viz 5
4. Objekty skládám do sebe a tím můžu řešit složitější procesy.
5. Když je jedna úroveň hotová, funguje jako černá skříňka a nemusím se starat o to, co probíhá uvnitř. Viz 3
6. Pro objekty stejného typu využiju dědění. Mají pak stejné rozhraní, ale jinou implementaci (tomu se říká polymorfismus).
Ad 1. Například mám následující proces - chci, aby si členové Webtrhu mohli koupit zvýraznění pro své obchody.
Ad 2. Na jaké balíčky můžu nákup rozložit? Co k tomu potřebuju?
Můžou si vybrat zvýraznění: Košík a položky v košíku
Operace pro košík:
- Přidat a odebrat položku
- Přepočítat cenu
Operace pro položky
- Vypočítat cenu podle typu obchodu, uživatelské role a kategorie
Můžou zaplatit: Můžou si nabít kredit, musím jim vystavit fakturu (reálný svět má svoje vlastní požadavky!)
Operace pro kredit:
- Nabít
- Zaplatit
- Refundovat
Operace pro faktury:
... podle stávajících zákonů
Fakturační údaje:
- Změnit údaje
- Ověřit údaje
Ad 3. Co je rozhraní a co je implementace?
Košík:
Rozhraní:
- Přidej položku
- Řekni celkovou cenu
Implementace
- Ulož položku tak a tak
- Spočítej celkovou cenu
Objekty, které košík využívají (jeho
klienti), volají jen rozhraní (co). Implementace (jak) je nezajímá.
Položka v košíku:
Rozhraní:
- Řekni mi svoji cenu
Implementace
- Vypočítej svoji cenu
Ad 4. Samotná
položka v košíku je důležitá a obsahuje svoji logiku, ale samotná není moc k ničemu. Až když ji začnu přidávat
do košíku, vzniká něco, co řeší úkol v reálném světě (proces nakupování).
Košík je naopak součástí vyššího procesu
objednávky, která mimo něj obsahuje
uživatele a ten obsahuje
fakturační údaje a
kredit.
Skládám objekty do sebe a vzniká mi něco užitečnějšího.
Ad 5. Třeba výpočet ceny zvýraznění je poměrně složitý proces, který zahrnuje parametry jako uživatelské skupiny, slevy a různé cenové hladiny. Klienta zvýraznění to ale
nezajímá. Klient (třeba košík) požádá:
- "Zvýraznění, řekni mi svoji cenu pro tohoto uživatele v této kategorii (rozhraní)."
Zvýraznění ji vypočítá (implementace - černá skříňka) a odpoví: "99".
Ad 6.
Pod pojmem "faktura" se skrývá několik různých "logik". Faktura pro lidi ve stejném státě jako dodavatel se chová jinak než faktura pro lidi v jiných členských státech EU. A ještě závisí na tom, jestli jsou plátci DPH.
Mám tedy několik typů faktur:
- Faktury, kde dodavatel platí DPH
- Faktury, kde odběratel platí DPH
- Faktury, kde se DPH neuplatňuje
Definuju pro všechny faktury stejné rozhraní:
- Přidej dodavatele
- Přidej odběratele
- Přidej položku
- Řekni mi celkovou DPH
- Řekni mi celkovou cenu
Ale každý typ má jinou implementaci.
Kouzlo tady leží v tom, že klienta faktury nezajímá, o jaký typ faktury jde. Díky polymorfismu volá všechny typy faktur stejně - všechny typy mají stejné rozhraní. Co probíhá uvnitř, je mu fuk (černá skříňka).
To je jen začátek. Třeba jiní lidé uvažují jinak, tohle je to, co z OOP čerpám já.
Nějaké další tipy:
- Definovat základní stavební kameny (třídy) a jejich rozhraní je nejdůležitější a asi i časově nejnáročnější. Vemte si na to hodně papírů a tužku, eventuálně zagooglujte, jestli vám sedne UML.
- Preferujte předávání objektů před děděním. Dědění používejte, jen pokud chcete využít polymorfismus (stejné rozhraní, jiná implementace).
- Používejte názvy z reálného světa. Žádné technické a abstraktní pojmy jako "array, set, process, field", ale hezky "cart, customer, invoice, money". Pro operace dtto. Názvy mají vycházet z problému, který řešíte, ne z implementace.
- Přečtěte si něco o návrhových vzorech / design patterns. Není to nic jiného než různé zažité a ověřené způsoby jak objekty skládat do sebe.
1. 9. 2011 11:44:36