Lekce 4 - Upomínač narozenin v VB.NET - Logická vrstva
V minulém dílu, Upomínač narozenin v VB.NET - Návrh formulářů, jsme navrhli kompletně formuláře pro naši aplikaci.
V tomto dílu se budeme zabývat návrhem logické vrstvy, tedy tříd, které obsahují logiku aplikace.
Osoba
V naší aplikaci budou zcela jistě figurovat osoby, vytvořme jim tedy třídu.
Vlastnosti
Osoba bude mít 2 vlastnosti: jméno a narozeniny. Jméno bude String, Narozeniny budou typu DateTime. Tyto vlastnosti nastavíme pomocí parametrického konstruktoru.
Public Class Osoba Public Jmeno As String Public Narozeniny As DateTime Public Sub New(jmeno As String, narozeniny As DateTime) Me.Jmeno = jmeno Me.Narozeniny = narozeniny End Sub End Class
Metody
Kromě konstruktoru bude třída disponovat metodami SpoctiVek() a ZbyvaDni().
SpoctiVek
Metoda vypočítá a vrátí aktuální věk osoby v celých letech. Výpočet bohužel není jen o tom odečíst dva datumy, jelikož TimeSpan neumí zjistit počet let, pouze počet dní. Výpočet věku tedy provedeme následujícím způsobem:
- Získáme si aktuální datum (bez času) pomocí DateTime.Today.
- Věk spočítáme jako rozdíl roků v aktuálním datu a datu narozenin. Asi je vám jasné, že tento věk není přesný. Pokud jsme se narodili 1.2.1990 a je 1.1.2010, není nám 20 let, ale jen 19. Z toho důvodu provedeme korekci.
- V případě, že je aktuální datum menší (dříve) než datum narození po přidání námi vypočítaných let, nastal výše uvedený případ a my věk o rok snížíme.
- Hotový věk vrátíme.
Kód metody bude následující.
Public Function SpocitejVek() As Integer Dim dnes = DateTime.Today Dim vek = dnes.Year - Me.Narozeniny.Year If dnes < Narozeniny.AddYears(vek) Then vek -= 1 End If Return vek End Function
ZbyvaDni
Metoda nám vrátí kolik dní zbývá do narozenin osoby. To zjistíme následujícím způsobem:
- Získáme si aktuální datum (bez času).
- Získáme datum dalších narozenin přičtením věku + 1 k datu narození.
- Data odečteme a celkový rozdíl ve dnech vrátíme. Jelikož je rozdíl typu double, musíme ho zkonvertovat na int.
Public Function ZbyvaDni() As Integer Dim dnes = DateTime.Today Dim dalsiNarozeniny As DateTime = Narozeniny.AddYears(SpocitejVek() + 1) Dim rozdil As TimeSpan = dalsiNarozeniny - dnes Return Convert.ToInt32(rozdil.TotalDays) End Function
ToString
Jelikož budeme osoby vypisovat, přepíšeme metodu ToString() tak, aby vracela jméno osoby:
Public Overrides Function ToString() As String Return Jmeno End Function
Správce osob
Další logickou komponentou aplikace bude správce osob. Třída se bude starat o osoby, bude je umět přidávat, odebírat a jejich seznam ukládat do souboru a opětovně načíst. Konečně bude umět mezi osobami vyhledat tu, která má nejbližší narozeniny.
Přidejte si k projektu tedy třídu SpravceOsob.
Vlastnosti a atributy
Jedinou veřejnou vlastností třídy je seznam osob. Seznam je typu BindingList. S touto kolekcí jsme se v seriálu ještě nesetkali. Jedná se o chytřejší list, který na sobě umí vyvolat událost změny v případě, že se změní jeho obsah. Díky tomuto mechanismu se automaticky obnoví všechny kontrolky na formuláři, které mají nastavený jako zdroj dat právě tento BindingList. Asi si dokážete představit, že obnovovat ručně desítky kontrolek na formuláři v případě změny může být velice nepřehledné. Jakmile v naší aplikaci přidáme novou osobu, bude ihned vidět v seznamu osob aniž bychom ho obnovovali, obnoví se sám. BindingList inicializujeme v konstruktoru Osoby. BindingList bude vyžadovat import System.ComponentModel. Visual studio ho naimportuje za vás, stačí mu to říct přes chytrou značku.
Pokud bychom chtěli implementovat i editace osob, musela by třída Osoba implementovat rozhraní INotifyPropertyChanged. Jakákoli změna (např. jména) by se poté automaticky projevila ve všech kontrolkách všech formulářů, kde osoba figuruje. Tímto se však pro zjednodušení zabývat nebudeme. Třída zatím vypadá takto:
Public Class SpravceOsob Public Property Osoby As BindingList(Of Osoba) Public Sub New() Osoby = New BindingList(Of Osoba) End Sub End Class
Metody
Kromě přidávání a odebírání bude třída umět i nalézt osobu s nejbližšími narozeninami. Ukládání a načítání osob do/ze souboru necháme na později.
Pridej
Metoda přidá novou osobu do BindingListu. Jelikož osobu přidáváme formulářem, hodí se nám, aby metoda brala v parametrech vlastnosti osoby a na jejich základě vytvořila novou instanci. Z data narození uložíme pouze část s datem, tedy bez času.
Před přidáním zkontrolujeme, zda jméno není příliš krátké nebo není zadané datum v budoucnosti. Pokud nějaká z těchto situací nastane, vyhodíme výjimku. Právě výjimky jsou správným způsobem, jak s chybami v objektových aplikacích pracovat.
Výjimky jsou detailněji popsané v sekci Práce se soubory v VB.NET. Pokud jste se s nimi ještě nesetkali, bude vám stačit vědět, že výjimka se vyvolá pomocí klíčového slova Throw, za kterým následuje instance výjimky. Výjimek máme několik typů včetně možnosti vytvořit si vlastní. V našem případě se nám hodí ArgumentException (chyba v argumentu). Do konstruktoru výjimky zadáváme text chyby. Jakmile je výjimka vyvolána, metoda již dále nepokračuje. Jak na chybu reagovat si ukážeme až budeme metodu volat z formuláře.
Public Sub Pridej(jmeno As String, datumNarozeni As DateTime) If jmeno.Length < 3 Then Throw New ArgumentException("Jméno je příliš krátké") End If If datumNarozeni.Date > DateTime.Today Then Throw New ArgumentException("Datum narození nesmí být v budoucnosti") End If Dim osoba As New Osoba(jmeno, datumNarozeni) Osoby.Add(osoba) End Sub
Odeber
Metoda odebere osobu z BindingListu. Protože vždy budeme chtít odebírat již hotovou osobu, bere metoda v parametru právě tu.
Public Sub deber(osoba As Osoba) Osoby.Remove(osoba) End Sub
NajdiNejblizsi
Metoda najde a vrátí osobu, která má nejbližší narozeniny. K vyhledání osoby v listu použijeme LINQ, to osoby uspořádá podle toho, kolik dní zbývá do jejich narozenin. Výsledek uložíme do kolekce, jejíž typ neuvedeme, jak je u LINQu zvykem. Následně vrátíme první osobu.
Public Function NajdiNejblizsi() As Osoba Dim serazeneOsoby = From o In Osoby Order By o.ZbyvaDni Return serazeneOsoby.First() End Function
Pokračovat budeme příště, Upomínač narozenin - Propojení prezentační a logické vrstvy, kdy aplikaci zprovozníme. Dosavadní zdrojový kód je ke stažení níže.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 204x (203.29 kB)
Aplikace je včetně zdrojových kódů v jazyce VB