September discount week
Pouze tento týden sleva až 80 % na e-learning týkající se MS Office
50 % bodů zdarma na online výuku díky naší Slevové akci!

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

Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

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.


 

Stáhnout

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

 

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
Článek pro vás napsal Michal Žůrek - misaz
Avatar
Jak se ti líbí článek?
Ještě nikdo nehodnotil, buď první!
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 (2)

 

 

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í!