Lekce 15 - Diář s databází v Kotlin - Dokončení

Kotlin Objektově orientované programování Diář s databází v Kotlin - Dokončení

Unicorn College ONEbit hosting Tento obsah je dostupný zdarma v rámci projektu IT lidem. Vydávání, hosting a aktualizace umožňují jeho sponzoři.

V minulé lekci, Diář s databází v Kotlin, jsme rozpracovali jednoduchý diář s databází pomocí Listu. V dnešním Kotlin tutoriálu aplikaci dokončíme.

Do třídy Diar přidejme pomocnou metodu zjistiLocalDateTime(), která vyzve uživatele k zadání data a času a vrátí instanci LocalDateTime nastavenou na tuto hodnotu. Nejprve si metodu ukažme, záhy si ji popíšeme:

private fun zjistiLocalDateTime(formatData: DateTimeFormatter): LocalDateTime {
        try {
                return LocalDateTime.parse(readLine(), formatData)
        } catch (e: Exception) {
                println("Nesprávně zadáno, zadejte prosím znovu")
                return zjistiLocalDateTime(formatData)
        }
}

Metoda vrací instanci LocalDateTime a v parametru bere formatter. V bloku try se pokoušíme přechroupat vstup od uživatele metodou parse(). Kdyby se projevila případná chyba v zadání (např. 30. únor a podobně), program přejde do bloku catch, uživatele upozorníme na chybu a zadání provedeme znovu. Všimněte si, že metoda volá sebe sama pro nové zadání. Je to běžná programátorská praktika, které se říká rekurze. Tuto metodu si schovejte, bude se vám jistě hodit i do budoucích konzolových aplikací :) K blokům try-catch se ještě podrobně vrátíme, až se budeme učit pracovat se soubory.

Do třídy si přidejme 2 veřejné companion objects (statické atributy). Budou to formattery data a času. Statické proto, aby byly použitelné i pro další třídy v naší aplikaci. Každá třída může používat tyto formattery, které máme definované na jednom místě.

companion object {
        val formatData = DateTimeFormatter.ofPattern("d.M.yyyy H:m")
        val formatDataBezCasu = DateTimeFormatter.ofPattern("d.M.yyyy")
}

Jeden formatter obsahuje datum i čas, jeden pouze datum bez času. Přejděme do třídy Zaznam.kt a metodu toString() pozměňme takto:

override fun toString(): String {
        return "${datumCas.format(Diar.formatDataBezCasu)} $text"
}

Kdybychom si dělali instanci formatteru znovu v každém záznamu, bylo by to nepraktické. Takto máme formattery na jednom místě a když se rozhodneme formát změnit, změníme ho jen ve třídě Diar. Se statikou ale opatrně, ne vždy ji je vhodné použít.

Vraťme se do třídy Diar. Přidáme 2 metody pro zjištění data a času:

private fun zjistiDatumCas(): LocalDateTime {
        println("Zadejte datum a čas ve tvaru [1.1.2013 14:00]:")
        return zjistiLocalDateTime(formatData)
}

private fun zjistiDatum(): LocalDate {
        println("Zadejte datum ve tvaru [1.1.2013]:")
        return zjistiLocalDateTime(formatDataBezCasu).toLocalDate()
}

Obě využívají naši metodu zjistiLocalDateTime(), ale dávají ji jiný formatter. Pomocí zjistiDatumCas() budeme zadávat datum a čas. Pomocí zjistiDatum() budeme zadávat pouze datum, všimněte si, že vrací pouze LocalDate. Druhá metoda bude sloužit k vyhledávání záznamů v určitý den, jelikož určitě nebudeme chtít vypsat záznam v danou hodinu a minutu, ale záznamy v daný den bez určení času.

Přidejme metodu vypisZaznamy(), která najde záznamy v daný den a vypíše je:

fun vypisZaznamy(den: LocalDateTime) {
        val zaznamy = databaze.najdiZaznamy(den, false)
        for (z in zaznamy) {
                println(z)
        }
}

Metoda pro vyzvání uživatele k vložení parametrů nového záznamu a jeho přidání do databáze bude následující:

fun pridejZaznam() {
        val datumCas = zjistiDatumCas()
        println("Zadejte text záznamu: ")
        val text = readLine()!!
        databaze.pridejZaznam(datumCas, text)
}

Zbývá záznamy vyhledávat a mazat. Metoda k vyhledání vrátí List s nalezenými záznamy (jen podle data, přesný čas nebude hrát roli). Vyzveme uživatele k zadání data a to předáme databázi. Výsledek zobrazíme:

fun vyhledejZaznamy() {
        // Zadání data uživatelem
        val datumCas = zjistiDatum().atStartOfDay()
        // Vyhledání záznamů
        val zaznamy = databaze.najdiZaznamy(datumCas, false)
        // Výpis záznamů
        if (zaznamy.size > 0) {
                println("Nalezeny tyto záznamy: ")
                for (z in zaznamy) {
                        println(z)
                }
        } else { // Nenalezeno
                println("Nebyly nalezeny žádné záznamy.")
        }
}

Mazání záznamů je triviální:

fun vymazZaznamy() {
        println("Budou vymazány záznamy v daný den a hodinu")
        val datumCas = zjistiDatumCas()
        databaze.vymazZaznamy(datumCas)
}

Jako poslední přidejme metodu pro vypsání úvodní obrazovky programu s aktuálním datem a časem a událostmi na dnešek a zítřek.

fun vypisUvodniObrazovku() {
        println()
        println()
        println("Vítejte v diáři!")
        val dnes = LocalDateTime.now()
        println("Dnes je: ${dnes.format(formatDataBezCasu)}")
        println()
        // výpis hlavní obrazovky
        println("Dnes:\n-----")
        vypisZaznamy(dnes)
        println()
        println("Zítra:\n------")
        val zitra = LocalDateTime.now().plusDays(1)
        vypisZaznamy(zitra)
        println()
}

Můžeme vítězoslavně přejít do Main.kt a vytvořit instanci diáře. Zde umístíme také hlavní cyklus programu s menu programu a reakcí na volbu uživatele. Je to ta nejvyšší vrstva programu:

fun main(args: Array<String>) {
        val diar = Diar()
        var volba = ""
        // hlavní cyklus
        while (volba != "4") {
                diar.vypisUvodniObrazovku()
                println()
                println("Vyberte si akci:")
                println("1 - Přidat záznam")
                println("2 - Vyhledat záznamy")
                println("3 - Vymazat záznam")
                println("4 - Konec")
                volba = readLine()!!
                println()
                // reakce na volbu
                when (volba) {
                        "1" -> diar.pridejZaznam()
                        "2" -> diar.vyhledejZaznamy()
                        "3" -> diar.vymazZaznamy()
                        "4" -> println("Libovolnou klávesou ukončíte program...")
                        else -> println("Neplatná volba, stiskněte libovolnou klávesu a opakujte volbu.")
                }
        }
}

Kód výše není složitý a již jsme tu podobný měli mockrát. Výslednou aplikaci jsem na vyzkoušení půjčil přítelkyni, zde vidíte výsledek :) :

Vítejte v diáři!
Dnes je: 13.6.2016 20:22

Dnes:
-----
13.6.2016 10:00 Shopping - Arkády Pankrác
13.6.2016 19:30 Vyvenčit mého yorkšírka Dennyho

Zítra:
------
14.6.2016 14:00 Power plate

Vyberte si akci:
1 - Přidat záznam
2 - Vyhledat záznamy
3 - Vymazat záznam
4 - Konec
2
Zadejte datum ve tvaru [1.1.2012]:
15.6.2016
Nalezeny tyto záznamy:
15.6.2016 9:30 Zkouška - Ekonomika cestovního ruchu

Tímto jsme si List osvojili a bude nám poměrně dlouho stačit. Na závěr bych dodal, že takto si můžete udělat databázi čehokoli. Můžete použít např. třídu Uzivatel z lekce Vlastnosti v Kotlin nebo kteroukoli jinou třídu. Můžete ukládat články, úlohy, slony, cokoli, co chcete v databázi spravovat. A co dál? V příští lekci, Rozhraní (interface) v Kotlin, to bude o rozhraní. V OOP nás toho čeká ještě dost :)


 

Stáhnout

Staženo 4x (18.17 kB)
Aplikace je včetně zdrojových kódů v jazyce Kotlin

 

 

Článek pro vás napsal Samuel Kodytek
Avatar
Jak se ti líbí článek?
Ještě nikdo nehodnotil, buď první!
Autor se věnuje všem jazykům okolo JVM. Rád pomáhá lidem, kteří se zajímají o programování. Věří, že všichni mají šanci se naučit programovat, jen je potřeba prorazit tu bariéru, který se říká lenost.
Aktivity (4)

 

 

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