4. diel - PRIPOMIENKOVÉ narodenín - Logická vrstva
V minulej lekcii, PRIPOMIENKOVÉ narodenín - Návrh formulárov , sme navrhli kompletne formuláre pre našu aplikáciu. V tomto tutoriále sa budeme zaoberať návrhom logické vrstvy, teda tried, ktoré obsahujú logiku aplikácie.
Osoba
V našej aplikácii budú celkom iste figurovať osoby, vytvorme im teda
triedu. Pred triedu nezabudnite dať modifikátor public
.
Vlastnosti
Osoba bude mať 2 vlastnosti: meno a narodeniny. Jmeno
bude
string
, Narozeniny
budú typu DateTime
.
Tieto vlastnosti nastavíme pomocou parametrického konstruktoru.
public class Osoba { public string Jmeno { get; set; } public DateTime Narozeniny { get; set; } public Osoba(string jmeno, DateTime narozeniny) { Jmeno = jmeno; Narozeniny = narozeniny; } }
Metódy
Okrem konstruktoru bude trieda disponovať metódami SpoctiVek()
a ZbyvaDni()
.
SpoctiVek
Metóda vypočíta a vráti aktuálne vek osoby v celých rokoch. Výpočet
bohužiaľ nie je len o tom odpočítať dva dátumy, pretože
TimeSpan
nevie zistiť počet rokov, iba počet dní. Výpočet
veku teda vykonáme nasledujúcim spôsobom:
- Získame si aktuálny dátum (bez času) pomocou
DateTime.Today
. - Vek spočítame ako rozdiel rokov v aktuálnom dátume a dátume narodenín. Asi je vám jasné, že tento vek nie je presný. Ak sme sa narodili 1.2.1990 a je 1.1.2010, nie je nám 20 rokov, ale len 19. Z toho dôvodu vykonáme korekciu.
- V prípade, že je aktuálny dátum menšia (skôr) ako dátum narodenia po pridaní nami vypočítaných rokov, nastal vyššie uvedený prípad a my vek o rok znížime.
- Hotový vek vrátime.
Kód metódy bude nasledujúci.
public int SpoctiVek() { DateTime dnes = DateTime.Today; int vek = dnes.Year - Narozeniny.Year; if (dnes < Narozeniny.AddYears(vek)) vek--; return vek; }
ZbyvaDni
Metóda nám vráti koľko dní zostáva do narodenín osoby. To zistíme nasledujúcim spôsobom:
- Získame si aktuálny dátum (bez času).
- Získame dátum ďalších narodenín pripočítaním veku + 1 k dátumu narodenia.
- Dáta odčítame a celkový rozdiel v dňoch vrátime. Keďže je rozdiel
typu
double
, musíme ho skonvertovať naint
.
public int ZbyvaDni() { DateTime dnes = DateTime.Today; DateTime dalsiNarozeniny = Narozeniny.AddYears(SpoctiVek() + 1); TimeSpan rozdil = dalsiNarozeniny - DateTime.Today; return Convert.ToInt32(rozdil.TotalDays); }
ToString
Keďže budeme osoby vypisovať, prepíšeme metódu ToString()
tak, aby vracala meno osoby:
public override string ToString() { return Jmeno; }
Správca osôb
Ďalšie logickú komponentom aplikácia bude správca osôb. Trieda sa bude starať o osoby, bude ich vedieť pridávať, odoberať a ich zoznam ukladať do súboru a opätovne načítať. Konečne bude vedieť medzi osobami vyhľadať tú, ktorá má najbližšie narodeniny.
Pridajte si k projektu teda triedu SpravceOsob
a urobte ju
verejnú.
Vlastnosti a atribúty
Jedinou verejnú vlastnosťou triedy je zoznam osôb. Zoznam je typu
BindingList
. S touto kolekciou sme sa v kurze ešte nestretli.
Jedná sa o múdrejší List
, ktorý na sebe vie vyvolať udalosť
zmeny v prípade, že sa zmení jeho obsah. Vďaka tomuto mechanizmu sa
automaticky obnoví všetky prvky na formulári, ktoré majú nastavený ako
zdroj údajov práve tento BindingList
. Asi si dokážete
predstaviť, že obnovovať ručne desiatky prvkov na formulári v prípade
zmeny môže byť veľmi neprehľadné. Akonáhle v našej aplikácii pridáme
novú osobu, bude ihneď vidieť v zozname osôb bez toho aby sme ho obnovovali,
obnoví sa sám. BindingList
inicializujeme v konstruktoru.
Ak by sme chceli implementovať aj editáciu osôb, musela by trieda
Osoba
implementovať rozhranie INotifyPropertyChanged
.
Akákoľvek zmena (napr. Mená) by sa potom automaticky prejavila vo všetkých
prvkoch všetkých formulárov, kde osoba figuruje. Týmto sa však pre
zjednodušenie zaoberať nebudeme.
Trieda zatiaľ vyzerá takto:
public class SpravceOsob { public BindingList<Osoba> Osoby { get; set; } public SpravceOsob() { Osoby = new BindingList<Osoba>(); } }
Metódy
Okrem pridávanie a odoberanie bude trieda vedieť aj nájsť osobu s najbližšími narodeninami. Ukladanie a načítanie osôb do / zo súboru necháme na neskôr.
Pridajme ()
Metóda pridá novú osobu do BindingList
u. Keďže osobu
pridávame formulárom, hodí sa nám, aby metóda brala v parametroch
vlastnosti osoby a na ich základe vytvorila novú inštanciu. Z dátumu
narodenia uložíme iba časť s dátumom, teda bez času.
Pred pridaním skontrolujeme, či meno nie je príliš krátke alebo nie je zadaný dátum v budúcnosti. Ak nejaká z týchto situácií nastane, vyhodíme výnimku. Práve výnimky sú správnym spôsobom, ako s chybami v objektových aplikáciách pracovať.
Výnimky sú detailnejšie popísané v sekcii Práca so súbormi v C# .NET. Ak ste sa s nimi ešte
nestretli, bude vám stačiť vedieť, že výnimka sa vyvolá pomocou
kľúčového slova throw
, za ktorým nasleduje inštancie
výnimky. Výnimiek máme niekoľko typov vrátane možnosti vytvoriť si
vlastný. V našom prípade sa nám hodí ArgumentException
(chyba
v argumentu). Do konstruktoru výnimky zadávame text chyby. Akonáhle je
výnimka vyvolaná, metóda už ďalej nepokračuje. Ako na chybu reagovať si
ukážeme až budeme metódu volať z formulára.
public void Pridej(string jmeno, DateTime datumNarozeni) { if (jmeno.Length < 3) throw new ArgumentException("Jméno je příliš krátké"); if (datumNarozeni.Date > DateTime.Today) throw new ArgumentException("Datum narození nesmí být v budoucnosti"); Osoba osoba = new Osoba(jmeno, datumNarozeni.Date); Osoby.Add(osoba); }
Odober
Metóda odoberie osobu z BindingList
u. Pretože vždy budeme
chcieť odoberať už hotovú osobu, berie metóda v parametri práve tú.
public void Odeber(Osoba osoba) { Osoby.Remove(osoba); }
NajdiNejblizsi
Metóda nájde a vráti osobu, ktorá má najbližšie narodeniny. Na
vyhľadanie osoby v liste použijeme LINQ
metódu OrderBy()
, ktorá osoby usporiada podľa toho, koľko dní
zostáva do ich narodenín. Výsledok uložíme do kolekcie, ktorej typ
neuvedieme a použijeme namiesto toho kľúčové slovo var
, ako je
v LINQ zvykom. Následne vrátime prvú osobu. Metódu by sme mali volať len
vtedy, keď sú v liste nejakej osoby. Hoci by z kódu malo byť jasné, čo
metóda robí, môžete sa samozrejme pozrieť na tutoriály v sekcii Kolekcia a LINQ v C# .NET, kde je technológia
LINQ detailne popísaná.
public Osoba NajdiNejblizsi() { var serazeneOsoby = Osoby.OrderBy(o => o.ZbyvaDni()); return serazeneOsoby.First(); }
Pokračovať budeme v nasledujúcej lekcii, PRIPOMIENKOVÉ narodenín - Prepojenie prezentačnej a logické vrstvy , kedy aplikáciu sprevádzkujeme. Doterajšie zdrojový kód je k stiahnutiu nižšie.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 1152x (342.7 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C#