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