7. díl - Upomínač narozenin ve VB.NET WPF - Logická vrstva

Ostatní jazyky Visual Basic .NET WPF Upomínač narozenin ve VB.NET WPF - Logická vrstva

V minulém dílu našeho seriálu tutoriálů o tvorbě okenních aplikací v VB .NET WPF 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 4 vlastnosti: jméno, narozeniny, věk a zbývající počet dní do nejbližších narozenin. Jméno bude string, Narozeniny budou typu DateTime, Vek integer a ZbyvaDni také integer. První dvě vlastnosti jsou jednoduché:

Public Property Jmeno As String
Public Property Narozeniny As DateTime

Tyto vlastnosti nastavíme pomocí parametrického konstruktoru. Třída vypadá zatím takto:

Public Class Osoba
        Public Property Jmeno As String
        Public Property Narozeniny As DateTime

        Public Sub New(jmeno As String, narozeniny As DateTime)
                Me.Jmeno = jmeno
                Me.Narozeniny = narozeniny
        End Sub

End Class

Další dvě vlastnosti nebudou pouhou proměnnou, ale budou obsahovat další logiku. Takové vlastnosti je potom možné pomocí bindingu jednoduše zobrazovat na formuláři.

Věk

Vlastnost 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:

  1. Získáme si aktuální datum (bez času) pomocí DateTime.Today.
  2. 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.
  3. 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.
  4. Hotový věk vrátíme.

Kód vlastnosti bude následující.

Public Property Vek As Integer
        Get
                Dim aktualniDatum As DateTime = DateTime.Today
                Dim stari As Integer = aktualniDatum.Year - Narozeniny.Year
                If aktualniDatum < Narozeniny.AddYears(Vek) Then
                        stari -= 1
                End If
                Return stari
        End Get

        Set(value As Integer)
        End Set
End Property
ZbyvaDni

Vlastnost nám vrátí kolik dní zbývá do narozenin osoby. To zjistíme následujícím způsobem:

  1. Získáme si aktuální datum (bez času).
  2. Získáme datum dalších narozenin přičtením věku + 1 k datu narození.
  3. 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 Property ZbyvaDni As Integer
        Get
                Dim dnes As DateTime = DateTime.Today
                Dim dalsinarozeniny As DateTime = Narozeniny.AddYears(Vek + 1)

                Dim rozdil As TimeSpan = dalsinarozeniny - dnes
                Return rozdil.TotalDays
        End Get

        Set(value As Integer)
        End Set
End Property

ToString

Jelikož budeme osoby vypisovat, přepíšeme třídě ještě 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

Správce osob disponuje třemi veřejnými vlastnostmi. První je seznam osob typu ObservableCollec­tion. 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ě tuto ObservableCollec­tion. 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. ObservableCollec­tion() inicializujeme v konstruktoru.

Pokud bychom chtěli implementovat i editaci osob, musela by třída Osoba implementovat rozhraní INotifyProper­tyChanged. 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 ObservableCollection(Of Osoba)

        Public Sub New()
                Osoby = New ObservableCollection(Of Osoba)()
        End Sub
End Class

Dalšími vlastnostmi jsou DnesniDatum, která vrátí dnešní datum. Dále NejblizsiOsoba, která vrátí osobu s nejbližšími narozeninami. Jejich kód:

Public Property NejblizsiOsoba As Osoba

Public Property DnesniDatum As DateTime
        Get
                Return DateTime.Now
        End Get

        Set(value As DateTime)
        End Set
End Property

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.

NajdiNejblizsi

Metoda najde a uloží osobu, která má nejbližší narozeniny. K vyhledání osoby v seznamu použijeme LINQ metodu OrderBy(), která 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. Metodu bychom měli volat jen tehdy, když jsou v seznamu nějaké osoby. Bude také privátní, jelikož ji budeme volat jen uvnitř třídy. Ačkoli by z kódu mělo být jasné, co metoda dělá, můžete se samozřejmě podívat na tutoriály v sekci (dostupné pouze pro C#) Kolekce a LINQ v C# .NET, kde je technologie LINQ detailně popsána.

Private Sub Najdinejblizsi()
        Dim serazeneOsoby = From o In Osoby Order By o.ZbyvaDni

        If serazeneOsoby.Count() > 0 Then
                NejblizsiOsoba = serazeneOsoby.First()
        Else
                NejblizsiOsoba = Nothing
        End If
End Sub
Pridej

Metoda přidá novou osobu do ObservableCollec­tion. 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.

Při zadávání data kontrolkou DatePicker dostaneme datum jako typ DateTime. Pokud je v datu Nothing, nebylo zadané a vyhodíme též výjimku.

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 = Nothing Then
                Throw New ArgumentException("Nebylo zadané datum narození")
        End If

        If datumNarozeni > 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)
        Najdinejblizsi()
End Sub

Na konci metody vyhledáme nejbližší osobu, protože to může být zrovna ta přidaná.

Odeber

Metoda odebere osobu z ObservableCollec­tion. Protože vždy budeme chtít odebírat již hotovou osobu, bere metoda v parametru právě tu. Po odebrání opět obnovíme nejbližší osobu.

Public Sub Odeber(osoba As Osoba)
        Osoby.Remove(osoba)
        Najdinejblizsi()
End Sub

Pokračovat budeme příště, kdy aplikaci zprovozníme. Dosavadní zdrojový kód je ke stažení níže.


 

Stáhnout

Staženo 73x (333.75 kB)
Aplikace je včetně zdrojových kódů v jazyce VB.NET

 

  Aktivity (1)

Článek pro vás napsal Michal Žůrek (misaz)
Avatar
Autor se věnuje tvorbě aplikací pro počítače, mobilní telefony, mikroprocesory a tvorbě webových stránek a webových aplikací. Nejraději programuje ve Visual Basicu a TypeScript. Ovládá HTML, CSS, JavaScript, TypeScript, C# a Visual Basic.

Jak se ti líbí článek?
Ještě nikdo nehodnotil, buď první!


 



 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!