11

Prohlížeč komiksů od návrhu po nasazení - 2. díl aneb Základní objektový návrh

autor Aleš Růžička | publikováno 17. prosince 2006


V této sérii článků bych vás rád provedl vývojem jednoduchého programu od návrhu až po nasazení. Půjde o prohlížeč komiksů z internetu. Je to snadná, ale přesto velmi použitelná aplikace (alespoň pro mne). Hlavně se na ní ale budu snažit ilustrovat co nejvíce možností, které nám .net 2.0 nabízí.

Jelikož aplikace, již vytváříme, bude dělána jednorázově, tak se nebudeme zbytečně zabývat návrhnovými vzory a jejich využitím. Pravděpodobně by to pouze prodloužilo návrh. Pro tentokrát to uděláme prostě "od oka" a později se podíváme, v čem by mohl být návrh lepší.

Dost řečí, diagram bude hovořit sám za sebe.

Zde jsme u první výhody - sice ne .net 2.0, ale vývojového prostředí. Toto vám žel Express edice Visual Studia neumožní. V tomto diagramu můžete navrhnout celou třídní strukturu a poté pouze doprogramovat funkční kód.

Naším základním požadavkem návrhu je snadnost přidávání nových komiksů. Navrženo je to tak, že stačí přidat pouze jednu třídu, která dědí abstraktní třídu Comics a přepsat její metodu GetImageUrlFromDate, zadat StartDate datum - od kdy byl komiks vydáván a EndDate - kdy přestal být vydáván (dnešní datum u komiksů, které jsou vydávány stále, včerejší u amatérských databází komiksů, kde se stripy vyskytují většinou s jednodením spožděním). Poté dopíšeme jméno do enumerátoru EComics a připíšeme jej do statické funkce GetComicsById třídy Comics.

public static Comics GetComisById(EComics Id)
{
    switch (Id)
    {
        case EComics.Garfield:
            return new Garfield();
        case EComics.CalvinAndHobbes: 
            return new CalvinAndHobbes();
        default:
            return null;
    }
}

Správně jste uhodli, že komiksové instance nevytvářím klasicky, ale na základě enumerátoru právě pomocí metody Comics.GetComicsById. Myšlekově je to tak trochu ukradené z návrhového vzoru Abstract Factory.

Abych dokázal, že vytvoření nového komiksu je velmi snadné, přikládám přepis třídy Garfield.

public class Garfield : Comics
{        
    public Garfield()
    {
        this.Id = EComics.Garfield;
        this.StartDate = new DateTime(1979, 1, 1);
        this.EndDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);
        //kvůli porovnávání datumů si chceme pořát držet verze s nulovýni hodinami, minutami, sekundami, ...
    }
    public override string GetImageUrlFromDate(DateTime Date)
    {   CommonTestsGetImageUrlFromDate(Date);
        string year = Date.Year.ToString();
        string month = (Date.Month + 100).ToString();
        string day = (Date.Day + 100).ToString();
        //stovky přidáváme kvůli konečnému formátu čísla
        //když je číslo jednomístné, pomocí tohoto před něj přídáme nulu
        //jedničku později uřízneme pomocí subtring
        return string.Format(
            "http://images.ucomics.com/comics/ga/{0}/ga{1}{2}{3}.gif",
            year,
            year.Substring(2, 2),
            month.Substring(1, 2),
            day.Substring(1, 2)
            );
    }
}

Třída ComicsData nám bude sloužit k ukládání dat o komiksech. Je to hlavně kvůli historii, která bude právě realizována pomocí vkládání a výběru objektů ComicsData v zásobníku.

Parametry třídy jsou klasicky zapouzdřeny. Příklad zapouzdřování v C# je zde:

private DateTime date;
public DateTime Date
{
    get
    {
        return date;
    }
    set
    {
        date = value;
    }
}

Výjimku zde tvoří funkce GetPath. Cestu tovořím dynamicky podle jména komiksu a datumu.

Nechci zde uvádět všechny zdrojové kódy o kterých jsme mluvili, protože by to zabralo příliš místa. Na konci článku proto umísťuji aktuální verzi programu, který zde popisuji. Bude ho čekat již pouze několik změn. Hlavně tedy přidání některých funkcí, které zatím chybí.

Program