IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

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

V minulém dílu, Upomínač narozenin v VB .NET WPF - Návrh oken, 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ě, Upomínač narozenin v VB .NET WPF - Propojení vrstev, 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 85x (333.75 kB)
Aplikace je včetně zdrojových kódů v jazyce VB

 

Předchozí článek
Upomínač narozenin v VB .NET WPF - Návrh oken
Všechny články v sekci
Okenní aplikace ve VB.NET WPF
Přeskočit článek
(nedoporučujeme)
Upomínač narozenin v VB .NET WPF - Propojení vrstev
Článek pro vás napsal Michal Žůrek - misaz
Avatar
Uživatelské hodnocení:
1 hlasů
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.
Aktivity