Cvičenie 3 - Objektovo-orientovaný návrh a Relácie

Cieľom tretieho cvičenia je precvičiť si návrh a vytváranie tried a definovanie relácií medzi triedami. Názvy a typ premenných a metód v nasledujúcich príkladoch sú zapísané v UML notácii.

Na začiatku budeme pracovať s nasledujúcim zadaním:

Zadanie

Navrhnite systém pre vytvorenie rozvrhu pre študentov.

  1. Existuje iba jeden globálny rozvrh.
  2. Rozvrh je zložený z rozvrhových jednotiek.
  3. Rozvrhová jednotka má pre daný čas priradenú miestnosť a predmet.
  4. Jedna rozvrhová jednotka má jedného vyučujúceho.
  5. Jeden študent môže byť priradený viacerým rozvrhovým jednotkám, a jedna jednotka môže mať viacero študentov.
  6. V rozvrhu by nemali byť žiadne kolízie pre študenta, vyučujúceho alebo miestnosť.

Postup návrhu

Pri objektovo-orientovanom návrhu môžete vo všeobecnosti postupovať podľa nasledujúceho návodu.

  1. Identifikujeme typy objektov pre ktoré navrhneme UML diagram tried.
  2. Do UML diagramu pridáme relácie medzi triedami. Rozhodneme či ide o asociáciu, agregáciu alebo kompozíciu. Pre každú reláciu určíme jej kardinalitu.
  3. Rozhodneme ako budeme reprezentovať relácie v objektoch pomocou členských premenných.
  4. Do UML diagramu doplníme ostatné dátové členské premenné.
  5. Definujeme konštruktory a metódy.

1. Identifikácia objektových typov

V texte zadania, ktorý sumarizuje používateľské požiadavky na navrhovaný systém identifikujeme typy objektov, ktoré musíme reprezentovať v našom programe.

1. Existuje iba jeden globálny rozvrh.
2. Rozvrh je zložený z rozvrhových jednotiek.
3. Rozvrhová jednotka má pre daný čas priradenú miestnosť a predmet.
4. Jedna rozvrhová jednotka má jedného vyučujúceho.
5. Jeden študent môže byť priradený viacerým rozvrhovým jednotkám, a jedna jednotka môže mať viacero študentov.
6. V rozvrhu by nemali byť žiadne kolízie pre študenta, vyučujúceho alebo miestnosť.

Vytvoríme UML diagram tried v ktorom pre každý typ vytvoríme jednu triedu (zatiaľ bez členských premenných, alebo metód).

2. Definovanie relácií medzi objektami

Podľa zadania identifikujeme v akom vzťaju sú jednotlivé objekty a pre každý vzťah definujeme reláciu medzi dvoma triedami. Pre každú reláciu rozhodneme či ide o asociáciu, agregáciu alebo kompozíciu. Na koniec priradíme ku každej relácii kardinalitu v obidvoch smeroch.

Výsledný UML diagram v tomto kroku by mohol vyzerať napr. takto:

UML diagram s reláciami medzi triedami

3. Definovanie členských premenných, konštruktorov a metód.

Každú reláciu, ktorú sme identifikovali medzi triedami, musíme reprezentovať pomocou členských premenných, ktoré patria jednej triede v relácii a ktoré majú typ druhej triedy v relácii. Podľa kardinality musíme definovať členskú premennú buď ako jednoduchý odkaz na jeden objekt, alebo ako pole viacerých objektov.

Napr. pre reláciu medzi triedou Rozvrh a RozvrhovaJednotka vytvoríme členskú premennú jednotky: RozvrhovaJednotka[], ktorá bude patriť triede rozvrh (keďže ide o kompozíciu, členskú premennú je vhodné definovať pre celok). Keďže rozvrh je zložený z viacerých rozvrhových jednotiek (kardinalita *), členská premenná musí byť pole viacerých objektov. Podobne definujeme aj členské premenné pre ostatné typy relácií, pričom väčšinou budú tieto premenné patriť triede RozvrhovaJednotka, keďže tento typ objektu prepája v našej aplikácii všetky ostatné typy.

Po definovaní členských premenných ktoré reprezetnujú relácie medzi objektami ešte doplníme ostatné dátové členské premenné (napr. názvy predmetov a miestností, mená osôb a čas rozvrhovej jednotky).

Po definovaní premenných pridáme konštruktory a metódy, pričom sa rozhodneme, ktoré členské premenné sa budú nastavovať pri vytváraní objektu v konštruktore a ktoré sa budú nastavovať v samostatných metódach. Napr. pri vytvorení objektu RozvrhovaJednotka nastavíme iba čas a predmet. Pri nastavení ostatných premenných (vyučujúceho, študentov a miestnosť), by sme mali skontrolovať, či neexistuje v rozvrhu časový konflikt, pričom potrebujeme mať prístup ku všetkým existujúcim rozvrhovým jednotkám. Preto budeme tieto premenné meniť v metódach, ktoré budú definované v triede Rozvrh (keďže rozvrh udržiava zoznam všetkých jednotiek).

Keďže má podľa zadania existovať iba jeden globálny rozvrh, pole rozvrhových jednotiek môžeme definovať ako statickú premennú priamo na úrovni triedy. Podobne, všetky metódy v triede Rozvrh, ktoré budú pracovať s rozvrhom definujeme ako statické, tzn. že nebudeme vytvárať žiadne objekty tejto triedy (viac rôznych rozvrhov) ale budeme meniť rozvrhové jednotky priamo na úrovni triedy.

Výsledný UML diagram tried je zobrazený na nasledujúcom obrázku.

Výsledný UML diagram pre plánovanie rozvrhu.

Úlohy

Úloha 3.1

Vytvorte balík rozvrh v ktorom vytvorte všetky triedy z predchádzajúceho príkladu návrhu. Pridajte všetky členské premenné a prázdne metódy a konštruktory.

Úloha 3.2

Naprogramujte konštruktory tak aby jednoducho inicializovali všetky členské premenné podľa hodnôch ich parametrov.

Úloha 3.3

V balíku rozvrh vytvorte triedu Program3_1 v ktorom vytvorte metódu main. V metóde main vytvorte a poprepájajte objekty pre cvičiaceho, štyroch študentov, jednu miestnosť, jeden predmet a jednu rozvrhovú jednotku podľa vášho cvičenia.

Úloha 3.4

Naprogramujte metódu pridajJednotku(jednotka: RozvrhovaJednotka): void, ktorá do statického poľa jednotky pridá na koniec nový prvok. Pri pridávaní nového prvku musíte vytvoriť nové pole s väčšou veľkosťou do ktorého skopírujte existujúce prvky a nastavte nový prvok.

Úloha 3.5

Naprogramujte metódu nastavVyucujuceho(jednotka: RozvrhovaJednotka, vyucujuci: Vyucujuci): void. Pri nastavovaní zistite, či má zadaný vyučujúci nejakú kolíziu na daný deň a hodinu rozvrhovej jednotky a ak áno, vyučujúceho nepriraďte a vypíšte chybovú správu.