NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!
NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.

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:

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

  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 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.Componen­tModel. Visual studio ho naimportuje za vás, stačí mu to říct přes chytrou značku.

Chytrá značka ve Visual Studiu - Okenní aplikace ve VB.NET Windows Forms

Pokud bychom chtěli implementovat i editace 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 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

 

Předchozí článek
Upomínač narozenin v VB.NET - Návrh formulářů
Všechny články v sekci
Okenní aplikace ve VB.NET Windows Forms
Přeskočit článek
(nedoporučujeme)
Upomínač narozenin - Propojení prezentační a logické vrstvy
Článek pro vás napsal Michal Žůrek - misaz
Avatar
Uživatelské hodnocení:
3 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