neděle 13. listopadu 2011

Pravidla pro pojmenování objektů v C# - část 1

Problematika je pro svoji obsáhlost rozdělena do více příspěvků:

  1. Úvod, jazyk, názvy tříd
  2. Názvy vlastností (properties), polí (fields) a proměnných (variables)
  3. Názvy metod a argumentů
  4. Další pravidla, názvy balíčků, testovací třídy

Úvod

U programového kódu se předpokládá, že splňuje syntaktickou a sémantickou správnost. Tyto dva požadavky jsou nutné pro vlastní fungování výsledné aplikace. Aby jste kód mohli efektivně udržovat a rozvíjet, je neméně důležitá dostatečná čitelnost kódu a správné názvosloví. Možná se Vám již někdy stalo, že jste se vrátili k Vašemu staršímu kódu a dlouze jste se snažili vyčíst, co jste takovým zápisem vlastně sledovali. Chvíli sami sebe přesvědčujete, že toto nemůže být Váš kód, takhle nepřehledně byste to přeci nikdy nenapsali. Nakouknete do historie v repository a zjistíte, že jste to byli opravdu Vy. Trochu se zastydíte a slíbíte si, že příště si na kódu dáte více záležet.

Pokud se dostanete ke kódu převzatému od nějakého "kouzelníka" (v některých firmách se těmto lidem nesprávně říká guru), může se situace ještě více zdramatizovat. Mnohdy se stává, že některé části kódu pro Vás zůstanou zapovězeny navždy a Vy se smíříte s tím, že kód sice něco dělá, ale netušíte jak. Zasáhnout do takového kódu vyžaduje dostatek osobní odvahy a pokud nemáte dostatečné pokrytí kódu testy, můžete úpravou nadělat nevědomky pěknou paseku.

Jak se naučíte psát čitelný a dobře spravovatelný kód? Pouze praxí, znalostí níže uvedených pravidel, učením se z vlastních i cizích chyb, skupinovým posuzováním kódu (code review). V tomto miniseriálu o názvosloví se Vám pokusím ukázat několik pravidel, které doporučuje odborná literatura, a které se mi osvědčily ve vlastní praxi.

Jazyk

Na začátku projektu se musíte rozhodnout jaký jazyk použijete. Nejedná se o jazyk programový, ale lingvistický. Svět programování mluví anglicky, ale přítomnost mateřské češtiny nemusí být na škodu. Většina z nás má lepší vyjadřovací schopnosti v češtině, angličtina je však mnohdy výstižnější a nedává nám příliš velký manévrovací (dezinformační) prostor. Záleží také na jazykovém složení Vašeho týmu. Pokud děláte lokální projekty s homogenním českým týmem (mohou být přimícháni i slovenští kolegové), můžete využít češtinu. V případě jazykově heterogenního týmu na výběr nemáte a budete zřejmě komunikovat a pojmenovávat programové objekty v angličtině. Pokud se Vám ovšem nepodaří husarský kousek, kdy naučíte třeba němce spisovné češtině ;-)

Můžete se také rozhodnout, že některé nejnižší vrstvy programového systému budou čistě anglické a vyšší vrstvy naopak české. Například jedna podvrstva datové vrstvy komunikující s nějakým persistentním frameworkem bude anglická a vrstvy od aplikační logiky (business logic layer) výše (vrstva služeb, prezentační vrstva) budou české. Především ve vrstvě aplikační logiky můžete s výhodou využít češtiny a její (pro české vývojáře) přirozené srozumitelnosti. Samozřejmě za dodržení určitých pravidel a jednotnosti. Toto kombinování jazyků však nedoporučuji.

Určitě se však vyhněte tomu, že v rámci jedné třídy budete mít namíchány názvy z více jazyků. Výjimku tvoří metody a property, které dědí Vaše třída. Např. třída pojmenovaná jako Objednavka může přepisovat metodu GetHashCode() nebo Equals(). Podle stejné logiky nemíchejte jazyky v rámci jednoho jmenného prostoru nebo ještě lépe v rámci celé assembly.

Jazyk použitý pro názvosloví programových objektů by měl korespondovat s jazykem použitým pro objekty v persistentním úložišti (v databázi). Jednoduše řečeno by mělo platit, že tabulky a sloupce jsou pojmenované ve stejném jazyce jako odpovídající třídy a vlastnosti.

V dalším textu budu používat názvosloví v češtině a budu předpokládat, že většina pravidel se dá aplikovat i na angličtinu.

Názvy tříd

  1. Používejte PascalCase notaci. V C# se nepíše polozkaObjednavky, ale PolozkaObjednavky. Omlouvám se tomu, koho jsem takovou samozřejmostí urazil ;-)

  2. Používejte jednotné číslo. Instancí Vaší třídy je jeden objekt. Název třídy Objednavky proto nedává smysl. Správně je Objednavka.

  3. Název by měl být významový a jednoznačný. Pokud v systému zadefinujete třídy Objednavka, DataObjednavky a ObjednavkaInfo zaděláváte si na problémy. Na první pohled není zřejmé, v čem se třídy liší. Pokud všechny reprezentují objektovou entitu odpovídající objednávce v reálném světě, jedná se o chybnou duplicitu v objektovém návrhu. Pokud tomu tak není a např. třída DataObjednavky umí nějakou obchodní logiku, např. vrací určité statistiky nad objednávkami, pak je jistě název takové třídy zvolen chybně.

  4. Používejte názvy z domény řešeného problému. Od doménového experta by návrhář systému (alias implementátor) měl dostat doménový slovník, který definuje pojmy a pravidla, které má aplikace pokrýt. Každá doména má svoji terminologii, která je standardizovaná a zúčastnění jí rozumí. Musíte těmto pojmům rozumět také a držet se dané terminologie v názvech tříd a vlastností.

  5. Používejte vhodné a standardizované přípony. Je běžné, že se v systému objevuje více tříd související s danou entitou. V takových případech je vhodné standardizovat určité přípony a zadefinovat jejich jednoznačný význam. Podívejme se na příklad objednávky a s ní souvisejících tříd:

    • Objednavka [datová vrstva] - třída reprezentující objednávku a její vlastnosti (mapovány na databázové sloupce tabulky s objednávkami).
    • ObjednavkaDao [datová vrstva] - třída odpovědná za CRUD (Create, Read, Update, Delete) operace, např. načtení objednávky podle jejího Id.
    • ObjednavkaBll [vrstva obchodní logiky] - třída zajišťující realizaci obchodních pravidel pro práci s objednávkami, např. vykrytí objednávky.
    • ObjednavkaDto [vrstva služeb] - zjednodušená třída (jejíž objekty jdou serializovat) pro přenos přes vrstvu služeb u vícevrstvých aplikací.
    • ObjednavkaSluzba [vrsta služeb] - třída nabízející logiku práce s objednávkami na úrovni komunikační vrstvy.
    • ObjednavkaObsluha [prezentační vrstva] - třída plnící funkci presenteru v MVP nebo controlleru v MVC návrhovém vzoru pro prezentační vrstvy.
    • ObjednavkaPohled [prezentační vrstva] - třída zajišťující vykreslení objednávky v závislosti na vybrané prezentační technologii.

  6. Nepoužívejte v názvech názvy objektových typů. Pokud třída řeší překlad českých slov na německá vnitřně pomocí hešovací tabulky, nepoužívejte název CeskoNemeckySlovnikHashTable, ale pouze CeskoNemeckySlovnik. Klienta třídy nezajímá její vnitřní implementace. Je pro něj důležitá pouze veřejná část třídy.

  7. Nezkracujte na úkor čitelnosti. Pokud je to vhodné použijte víceslovný název třídy, který přesněji vymezí význam třídy. V době pomůcek pro efektivitu psaní kódu typu IntelliSense se dlouhých názvů bát nemusíte.

    Pozor na situace, kdy se nedá význam třídy popsat jednoduše. V těchto případech se může jednat o blikající kontrolku chybného návrhu třídy, konkrétně o porušení pravidla jedné zodpovědnosti. Např. třída AdresaABankovniUcetZamestnance zřejmě slučuje dvě věci (adresu a bankovní účet), které by měly být odděleny do dvou samostatných tříd.

  8. Nebojte se refaktorovat název. Nemusíte ideální název třídy vymyslet hned napoprvé. Ale pokud časem přijdete na výstižnější název, nebojte se jej refaktorovat. Kód musíte neustále vylepšovat.

  9. Nepoužívejte slovesa v názvech. Třída ZamestnanecMajiciDohodu má možná literárně hodnotný název, ale do názvu třídy něco takového nepatří. V tomto případě se zřejmě jedná navíc o chybný objektový návrh a chybnou dědičnost.

3 komentáře:

  1. Po zveřejnění tohoto příspěvku jsem chvíli přemýšlel, zda-li jsem nestřelil trochu mimo se seriálem o pravidlech názvosloví v češtině. Netušil jsem, jaké procento českých firem používá např. ve vrstvě obchodní logiky české názvosloví. Mé pochybnosti však rozptýlil poměrně rychle Robert Haken, který v zahajovacím bloku MS Festu 2011 probral podobná pravidla pro pojmenování databázových struktur ... a v češtině.
    Nahrávka jeho prezentace je dostupná na
    http://knowledge-base.havit.cz/files/folders/ms-fest-2011/entry732.aspx

    OdpovědětVymazat
  2. Cokoliv pojmenovat v programování česky je začátek problému. Pamatuji si náš projekt, 8 let práce, perfektní implementace ... no a pak nás koupili němci :-) strašně se jim to líbilo, třeba pojmenovávání sloupců česky v tabulce :-)

    OdpovědětVymazat
    Odpovědi
    1. Ach ti němci, stále ještě se nenaučili pořádně česky! ;)

      Pokud projekt překročí hranice českého rybníka, pak je použití angličtiny určitě nezpochybnitelé.

      Spousta projektů je ale menšího regionálního rozsahu a v tom případě asi čeština nikomu nevadí. A například názvosloví tříd ve vrstvě obchodní logiky může být čitelnější. Ale nechci působit jako dogmatický zastánce češtiny ve zdrojových kódech ;)

      Pravidla uvedená v tomto příspěvku se dají aplikovat i na anglicky psaný kód.

      Vymazat