Programování pro PalmOS počítače krok za krokem (60)

Dnes otevíráme pátou kapitolu - povíme si v ní jednak o seznamech, které jsou velmi silným nástrojem pro uživatelský vstup, a jednak se naučíme ovládat černobílý grafický výstup na displej Palm Pilotu. Ke kreslení se pak vrátíme ještě v sedmé kapitole, kdy si povíme o pokročilých prvcích grafiky a barvách. Zatím budeme postupně vytvářet jednoduchý černobílý kreslicí program.

Programování pro Palm Piloty krok za krokem - kapitola 5

V této kapitole se naučíme dvě důležité věci, které spolu na první pohled zdánlivě nesouvisejí. Nejprve se naučíme používat seznamy a tlačítka výběru ze seznamu. Důležitější však bude, že součástí kapitoly bude úvod do principu kreslení na displeji počítačů Palm Pilot a kompatibilních - čáry, rámečky, text a obrázky. První pohled často bývá zatížen chybou - uvidíte, jak se vám znalosti z obou nesouvisejících částí této kapitoly propojí.

5.1. Styly psaní programů; ochranné a agresivní programování

Podobně jako u jakékoli tvůrčí činnosti, i při psaní programů můžeme používat odlišné styly. Neexistuje správný způsob, jak daný program nebo určitou funkci vytvořit: nejvíc záleží stejně na fantazii programátora.

Nebudeme si tu uvádět konvence pro zápis zdrojového textu, jména proměnných ani pozice otevíracích závorek. Soustředíme se na funkce programu, který píšete. Prohlédněte si funkci v následujícím rámečku, kterou jsme vybrali z předchozí kapitoly a trochu ji zjednodušili:

void KopirujTextPolicka(UInt16 idPolicka, Char* kam)
{
    MemHandle ovladacTextu = FldGetTextHandle((FieldPtr)Objekt(idPolicka));
    Char* textPolicka = (Char*)MemHandleLock(ovladacTextu);
    StrCopy(kam, textPolicka);
    MemHandleUnlock(ovladacTextu);
}

Příklad v předchozím rámečku je příkladem agresivně napsané funkce. Tato funkce vychází z celé řady předpokladů - například pokud programátor omylem uvede nesprávnou identifikaci políčka, dojde ke kritické chybě operačního systému PalmOS (první řádek funkce). K jiné, neméně kritické chybě (druhý řádek) dojde, i pokud nebyl v políčku při volání této funkce žádný text. I třetí řádek může být zdrojem fatální chyby: stačí, aby byl text v políčku delší, než je rozměr proměnné kam. Zkusíme teď funkci upravit tak, aby počítala s co nejvíce situacemi, ke kterým může dojít.

Jaké komplikace si můžeme vymyslet?

  • kterýkoliv parametr může být programátorem zadán nesprávně
  • řetězcové proměnné nemusí mít postačující délku k uložení kopírovaného textu
  • při volání systémové funkce PalmOS může dojít k chybě
  • kterákoliv funkce našeho programu může obsahovat chybu, kterou jsme ještě neobjevili
  • globální proměnné nemusí nutně být správně inicializovány
  • program může být spuštěn na modelu, který nepodporuje hardwarové funkce, které využíváme
  • musíme informovat uživatele i programátora o chybách

Teď přepíšeme uvedenou funkci tak, aby byla psána v obranném stylu - tj. aby počítala s co nejvíce možnostmi, které mohou nastat (možná bychom mohli zavést termín paranoidní styl - to se mi však moc nelíbí). Zdrojový text se nám trochu prodlouží:

// Přidáme nový parametr - pocet - který udává maximální počet 
// zkopírovaných znaků

void KopirujTextPolicka(UInt16 idPolicka, Char* kam, UInt16 pocet)
{
    FieldPtr policko;
    MemHandle ovladacTextu;
    Char* textPolicka;
    Char prazdnyRetezec[2] = '\0\0';

    policko = (FieldPtr)Objekt(idPolicka);

    if(!policko)
    {
        // chyba programátora: objekt číslo idPolicka třeba neexistuje
        // zde je třeba na chybu upozornit programátora

        return;
    }

    ovladacTextu = FldGetTextHandle(policko);

    if(!ovladacTextu)
    {
        // políčko ještě nebylo inicializováno - vrátíme prázdný řetězec

        textPolicka = prazdnyRetezec;
    }
    else
    {
        textPolicka = (Char*)MemHandleLock(ovladacTextu);
    }

    // parametr kam může být zadán špatně
	
    if(kam)
    {
        StrNCopy(kam, textPolicka, pocet);
    }

    if(ovladacTextu)
    {
        MemHandleUnlock(ovladacTextu);
    }
}

Už z předchozího příkladu vidíme, že obranný styl programování vede k psaní funkcí, které obsahují více řádků a jsou vykonávány o něco pomaleji. Oba dva popisované přístupy mají své výhody i nevýhody, které přehledně shrneme v následující tabulce:

Agresivní styl Obranný styl
  • Funkce jsou jednodušší, kód programu je kratší
  • Rychlejší vývoj programu
  • Více srozumitelný, "elegantnější" kód
  • Rychlejší aplikace
  • Menší výsledný *.prc soubor
  • Bezpečnější
  • Menší pravděpodobnost havárie systému
  • Tolerantní k chybám programátora i uživatele
  • Rychlejší ladění aplikace
  • Není-li důkladně testován, může vést k neočekávanému chování programu, až ke kritické chybě PalmOS
  • Netoleruje chyby programátora
  • Pomalejší ladění aplikace
  • Často ztrpčuje život uživateli
  • Funkce jsou delší, méně přehledné
  • Pomalejší vykonávání programu
  • Soubor *.prc je větší
  • Více zdrojového textu vede k často delší době vývoje

Není jednoznačně dané, který z uvedených stylů je lepší. Hlavní výhodou obranného stylu je větší bezpečnost programů; agresivní styl vede k nutnosti lépe si uvědomit strukturu programu a výsledná aplikace je rychlejší. V naší knize se budeme vždy držet kompromisu mezi oběma styly. Pro vlastní programy vám doporučuji začínat se stylem obranným a teprve postupně, jak budete získávat zkušenosti s operačním systémem PalmOS, jej případně opouštět.


Po tomto krátkém úvodu si povíme, co jsou to výzvy, jak je definujeme a využíváme v našich programech.