Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
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í.

13. diel - Diár s databázou v Dart

V minulej lekcii, Kolekcia Set, Queue a Map v Dart , sme si predstavili kolekcie Dart. V tomto tutoriále si do kolekcií skúsime uložiť objekty.

Najprv som chcel urobiť databázu užívateľov, ale užívateľa sme tu už niekoľkokrát mali. Keďže sme sa nedávno naučili dátum a čas, naprogramujeme si diár. Do databázy budeme ukladať jednotlivé záznamy a vždy vypíšeme ten dnešný a zajtrajší. Databáza to nebude samozrejme tá v tom pravom slova zmysle (na to ešte nemáme skúsenosti), ale bude sa jednať práve o List v operačnej pamäti počítača. Bude umožňovať záznamy pridávať, hľadať je podľa dátumu a mazať podľa dátumu a času.

Založte si nový projekt, ktorý pomenujeme diar.

Záznam

Najprv si urobme triedu, ktorej inštancia budeme ukladať. Nazvime ju Zaznam. Záznam v diári sa bude viazať k nejakému dátumu a času. Tiež bude obsahovať nejaký text. Napr .: 12. ledna 2013 - Vyvenčit psa. To je asi všetko, trieda môže vyzerať takto:

class Zaznam {
    DateTime datumCas;
    String text;

    Zaznam(this.datumCas, this.text);

    @override
    String toString() {
        return '$datumCas $text';
    }
}

Trieda v podstate slúži len k záznamu dát a nemá žiadne metódy (až na konštruktor a toString()).

Databázy

Pretože program bude o niečo zložitejšie, rozdelíme ho do viacerých objektov (vrstiev). Záznam máme, teraz si vytvoríme objekt Databaze, v ktorej budú záznamy uložené. Bude mať privátne zoznam typu Zaznam. Diár bude umožňovať záznamy pridávať, mazať a vyhľadávať podľa dátumu. K projektu teda pridáme triedu Databaze:

class Databaze {
    List<Zaznam> _zaznamy = [];
}

Trieda teda slúži len pre manipuláciu s dátami. Obsahuje vnútorné kolekciu _zaznamy. Dodajme triede metódy pre pridanie, vymazanie a vyhľadanie záznamu.

Pridanie záznamu by malo byť jasné:

void pridejZaznam(DateTime datumCas, String text) {
    _zaznamy.add(new Zaznam(datumCas, text));
}

Ako druhú metódu pridajme nájdenie záznamov v daný deň. Metóda bude vracať zoznam nájdených záznamov, pretože ich pre ten deň môže byť v databáze viac. Záznamy budeme môcť vyhľadávať podľa dátumu i času alebo len podľa dátumu. Môžeme tak nájsť záznamy v konkrétny deň bez ohľadu na to, v akú sú hodinu. Podľa čoho budeme chcieť vyhľadávať bude udávať parameter dleCasu typu bool. Pokiaľ bude false, hľadáme len podľa dáta bez ohľadu na čas. Zoznam si najprv vytvoríme a potom do neho pridávame záznamy, ktoré zodpovedajú hľadanému dátume. Zodpovedať musí buď celé dátum a čas (ak hľadáme aj podľa času) alebo len časť dní, ak hľadáme len podľa dátumu. Naplnený zoznam s nájdenými záznamami vrátime.

List<Zaznam> najdiZaznamy(DateTime datum, bool dleCasu) {
    List<Zaznam> nalezene = [];

    _zaznamy.forEach((Zaznam zaznam) {
        if ((dleCasu && zaznam.datumCas.isAtSameMomentAs(datum)) ||
            (!dleCasu && zaznam.datumCas.difference(datum).inDays == 0 && zaznam.datumCas.day == datum.day))) {
            nalezene.add(zaznam);
        }
    });

    return nalezene;
}

Nakoniec pridáme vymazanie záznamov v určitú dobu. To vykonáme pomocou metódy najdiZaznamy() a nájdené záznamy jednoducho proiterujeme a zo zoznamu odstránime. Budeme mazať podľa presného dátumu i času, 2. parameter u metódy najdiZaznamy() bude teda true:

void vymazZaznamy(DateTime datum) {
    List<Zaznam> nalezeno = najdiZaznamy(datum, true);
    nalezeno.forEach((Zaznam zaznam) {
        _zaznamy.remove(zaznam);
    });
}

Diár

Teraz si pridáme k projektu poslednej triedu, bude to samotný diár. Nazvime ju Diar. Ten už bude obsahovať metódy pre komunikáciu s užívateľom. Všimnite si, ako aplikáciu rozdeľujeme a jednotlivé jej časti zapuzdruje. Zoznam je zapuzdrený v databáze, ktorá nad ním postavila ďalšie metódy pre bezpečnú manipuláciu s jeho obsahom. Samotnú databázu teraz vložíme do diára. Tým oddelíme logiku a prácu s dátami od komunikácie s užívateľom a ďalšími vstupy / výstupy programu. Trieda Diar teda bude komunikovať s užívateľom a dáta od neho odovzdá databázu.

class Diar {
    Databaze _databaze = new Databaze();
}

Ako ďalšie pridajme pomocnú metódu _zjistiDatumCas(), ktorá vyzve používateľa na zadanie dátumu a času a vráti inštanciu DateTime nastavenú na túto hodnotu. Jediným bodom na premýšľanie je tu validácia vstupu od užívateľa:

DateTime _zjistiDatumCas() {
    print('Zadejte datum a čas ve tvaru [2018-01-14 14:00]:');
    DateTime datumCas;

    while (true) {
        try {
            datumCas = DateTime.parse(stdin.readLineSync(encoding: UTF8));
            break;
        } catch (e) {
            print('Chybné zadání, zadejte znovu datum a čas:');
        }
    }

    return datumCas;
}

Pridajme metódu vypisZaznamy(), ktorá nájde záznamy v daný deň a vypíše je:

void vypisZaznamy(DateTime den) {
    List<Zaznam> zaznamy = _databaze.najdiZaznamy(den, false);
    zaznamy.forEach((Zaznam zaznam) => print(zaznam));
}

Keďže metóda forEach() aplikuje funkciu o jednom parametri, ktorú jej odovzdávame v parametri, možno kód zjednodušiť a odovzdávať iba funkciu print():

void vypisZaznamy(DateTime den) {
    List<Zaznam> zaznamy = _databaze.najdiZaznamy(den, false);
    zaznamy.forEach(print);
}

Metóda pre vyzvanie užívateľov k vloženie parametrov nového záznamu a jeho pridanie do databázy bude nasledujúci:

void pridejZaznam() {
    DateTime datumCas = _zjistiDatumCas();
    print('Zadejte text záznamu:');
    String text = stdin.readLineSync(encoding: UTF8);
    _databaze.pridejZaznam(datumCas, text);
}

Zostáva záznamy vyhľadávať a mazať. Metóda na vyhľadanie vráti zoznam s nájdenými záznamami (len podľa dátumu, presný čas nebude hrať úlohu). Vyzveme užívateľa na zadanie dátumu a to odovzdáme databázu. Výsledok zobrazíme.

void vyhledejZaznamy() {
    // Zadání data uživatelem
    DateTime datumCas = _zjistiDatumCas();
    // Vyhledání záznamů
    List<Zaznam> zaznamy = _databaze.najdiZaznamy(datumCas, false);
    // Výpis záznamů
    if (zaznamy.length > 0) {
        print('Nalezeny tyto záznamy:');
        zaznamy.forEach(print);
    } else {
        // Nenalezeno
        print('Nebyly nalezeny žádné záznamy.');
    }
}

Mazanie záznamov je triviálne:

void vymazZaznamy() {
    print('Budou vymazány záznamy v daný den a hodinu');
    DateTime datumCas = _zjistiDatumCas();
    _databaze.vymazZaznamy(datumCas);
}

Ako posledný pridajme metódu pre vypísanie úvodnej obrazovky programu s aktuálnym dátumom a časom a udalosťami na dnešok a zajtrajšok.

void vypisUvodniObrazovku() {
    print('''

Vítejte v diáři!
Dnes je ${new DateTime.now()}

Dnes:
------''');
    vypisZaznamy(new DateTime.now());
    print('''

Zítra:
------''');
    vypisZaznamy(new DateTime.now().add(new Duration(days: 1)));
    print('');
}

Môžeme víťazoslávne prejsť do main.dart a vytvoriť inštanciu diáre. Tu umiestnime tiež hlavný cyklus programu s menu programu a reakcií na voľbu používateľa. Je to tá najvyššia vrstva programu:

void main() {
    // instance diáře
    Diar diar = new Diar();
    String volba = '0';
    // hlavní cyklus
    while (volba != '4') {
        diar.vypisUvodniObrazovku();
        print('''
Vyberte si akci:
1 - Přidat záznam
2 - Vyhledat záznamy
3 - Vymazat záznam
4 - Konec
''');
        volba = stdin.readLineSync(encoding: UTF8).trim().split('').first;
        // reakce na volbu
        switch (volba) {
            case '1':
                diar.pridejZaznam();
                break;
            case '2':
                diar.vyhledejZaznamy();
                break;
            case '3':
                diar.vymazZaznamy();
                break;
            case '4':
                break;
            default:
                print('Neplatná volba, stiskněte libovolnou klávesu a opakujte volbu.');
                break;
        }
    }
}

Kód výška nie je zložitý a už sme tu podobný mali veľakrát. Výsledok našej aplikácie:

Konzolová aplikácia
Vítejte v diáři!
Dnes je 2018-01-12 23:48:06.541360

Dnes:
------
2018-01-12 00:00:00.000 Učit se programovat
2018-01-12 19:30:00.000 Posilovna!

Zítra:
------
2018-01-13 07:35:00.000 Jít ven běhat! (Alespoň 30 min)

Vyberte si akci:
1 - Přidat záznam
2 - Vyhledat záznamy
3 - Vymazat záznam
4 - Konec

Týmto sme si prácu s kolekciami, konkrétne so zoznamom, osvojili ešte lepšie a bude nám to pomerne dlho stačiť. Na záver by som dodal, že takto si môžete urobiť databázu čohokoľvek. Môžete ukladať články, úlohy, slony, čokoľvek, čo chcete v databáze spravovať. A čo ďalej? V budúcej lekcii, , to bude o rozhranie a mixin. V OOP nás toho čaká ešte dosť.:)


 

Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 4x (3.62 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Dart

 

Predchádzajúci článok
Kolekcia Set, Queue a Map v Dart
Všetky články v sekcii
Objektovo orientované programovanie v Dart
Článok pre vás napísal Honza Bittner
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
FIT ČVUT alumnus :-) Sleduj mě na https://twitter.com/tenhobi a ptej se na cokoli na https://github.com/tenhobi/ama.
Aktivity