Internet Info, s.r.o. Lupa Měšec Podnikatel Root Zdroják DigiZone Slunečnice Vitalia TopDrive KupDnes Navrcholu NovýTarif Dobrý web Weblogy Woko Jagg Computer.cz SK: MojeLinky

Hlavní navigace

Jak psát hezký kód I

Programování nespočívá jen v zapsání algoritmu v určitém programovacím jazyku tak, aby výsledek fungoval – tedy syntakticky a sémanticky správně. To je u programování samozřejmost. Programátoři ale často zapomínají, že po nich budou číst kód i jiní, někdy i oni sami. Napsat kód nejen správně, ale i „hezky“, pak ušetří spoustu práce.

Tweetni to Twitter Jaggni to! Jagg Del.icio.us Delicious

Jak psát kód hezky nelze jednoduše říct, protože každý, opravdu každý, kód lze napsat lépe, než jak momentálně vypadá. Ať už se snažíme sebevíc, vždy je možnost, jak ho vylepšit. Nikdy proto nenapíšeme bezvadný kus kódu, ale to neznamená, že na psaní hezkého kódu máme rezignovat a psát špatně kód, který nelze znovu použít. Existuje několik všeobecných zásad, které pokud dodržíte alespoň trochu, tak se bude váš kód lépe číst nejen vám, ale i ostatním lidem, kteří ho budou používat, upravovat či jen pročítat. Nemluvě o dobrém pocitu z dobře odvedené práce.

Než se pustíme do samotných zásad, tak je na místě upozornit, že nelze psát pěkný kód ihned. Nejprve je třeba napsat kód „na hrubo“ a poté ho upravovat, dokud nebude dobrý. Zdůrazňuji slovo dobrý, protože kdybyste chtěli kód upravovat do ideálního stavu, tak u něj dříve umřete.

Já osobně nejprve napíši nějaké monstrum podle zadání (dílčí část, nikoliv celou aplikaci – upravit kód celé aplikace znamená napsat jej všechen znova a lépe), poté se pozastavím a zamyslím se, zda by to šlo upravit a jak. Upravit to lze samozřejmě vždy a záleží na daném problému, jak to udělat. Rozmyslím se, kód upravím a opět se na něj podívám, zda je dobrý nebo zda potřebuje ještě nějakou úpravu. Takto se to opakuje, dokud nejsem s výsledkem spokojený. (Čas od času se stane, že z původního monstra nic nezůstane a vše se změní, samozřejmě k lepšímu.) Až poté pokračuji dál s další částí. – pozn.aut.

Hezký kód

Definovat nějak hezký kód, jak bylo řečeno, nelze a nikdy to ani nepůjde. Záleží na každém kodérovi, jak si definici vytvoří. Můj pohled na čistý kód je takovýto: „Čistý kód je takový kód, který dělá přesně to, co očekáváte. Je to takový kód, který lze dobře číst, a který lze číst bez skákání.“ Pojem Čistý kód mám ze stejnojmenné knížky od Roberta C. Martina a doporučuji ji mít ve své knihovničce všem, kteří to s programováním myslí alespoň trochu vážně.

Názvy proměnných, funkcí, tříd

Pokud začnete programovat v jakémkoliv jazyce, tak začnete s vytvořením proměnné, do které hodíte nějaký řetězec, většinou „Hello World!“, a pozdravíte svět. Je to logické, že se nezačne uprostřed, třeba se zachytáváním výjimek, a proto já také začnu u proměnných, resp. názvů proměnných, ale i funkcí, tříd, …

Názvy proměnných by měly být určeny podle toho, jakou informaci v sobě nesou. Názvy funkcí naopak podle toho, co funkce provádí. Podobné pravidlo je vhodné dodržovat pro všechny věci, které se nějak pojmenovávají. Některé věci se pojmenovávají standardně, chcete-li stejně, u ostatních se musíme dobře rozmyslet. Podívejte se na následující příklad:

def zjistiJestliJeTentoRokPrestupny( x ):
    if x % 4 == 0:
        return True
    return False

Pozn: Algoritmus je pouze ilustrační a nezohledňuje výjimky z pravidel, např. že přestupné nejsou roky dělitelné 100, pokud nejsou zároveň dělitelné 400. (V tomto článku bude veškerý ukázkový kód v Pythonu.)

Z příkladu je vidět, že takovéto názvy se do kódu nehodí. Název funkce je velmi dlouhý a nikoho nebude bavit ho psát, natož pak zjišťovat proč to nefunguje a hledat ve volání funkce překlep. Vhodný název by mohl být třeba tento: jePrestupny. Argument, kterým se předává rok, je naopak zase moc krátký a hlavně nicneříkající. Pokud se podíváme na tělo funkce, tak vůbec nemáme tušení, co v tom x je za hodnotu a musíme se podívat do hlavičky funkce. Zde by byl vhodnější například název  rok.

Zapamatujme si tedy, že není vhodné používat zbytečně dlouhé názvy, a také se vyhněte používání jednopísmenných, nic neříkajících, názvů. Podívejte se na další příklad:

def secti( l, x ):
    a = 0
    for v in l:
        if v[0] == x:
            a += v[1]
    return a

Po přečtení asi vůbec netušíte, co se může dít. Podle názvu funkce tušíte, že se bude něco sčítat, ale nevíte co a jak. Porovnejte tento příklad s následujícím, který je úplně totožný, až na to, že jsou jiné názvy. Hned se to čte lépe, že?

def soucetHodnotSID( pole, id ):
    soucet = 0
    for polozka in pole:
        if polozka[ID] == id:
            soucet += polozka[HODNOTA]
    return soucet

I dobré pravidlo má rozumné výjimky. Jako odstrašující příklad uvádím firmu, která do svých „coding rules“ dala pravidlo, že v kódu nesmí být použity jednopísmenné proměnné. Nikde, nikdy, basta! Vedlo to k tomu, že programátoři psali např. cykly jako for (promennaCyklu=0; promennaCyklu<50; promennaCyklu++) Zrovna řídicí proměnné cyklů FOR jsou už desítky let běžně pojmenovávány I, J, … takže v tomto případě nadělá rigidní lpění na pravidle spíš víc škody než užitku. – pozn.red.

V předchozím příkladě si můžete všimnout použití konstant. To je také velmi důležité. Místo nesmyslných čísel rozházených všude možně v kódě použijte konstantu, která řekne víc než samotné číslo. Metoda v příkladu pod tímto odstavcem ukazuje změnu šířky – víte, proč se to násobí 39? Ne? No přeci protože 1 cm = 39 px (na mém monitoru) a my kreslíme v měřítku 1:1. Mnohem lepší by tam byla konstanta, pojmenovaná třeba PXNACM, než číslo. Používejte konstanty všude tam, kde je to vhodné.

class Meritko1ku1( Kresleni ):
    ...
    def zmenSirku( self, novaSirka ):
        self.sirka = novaSirka * 39
    ...

Funkce

Jak psát funkce byste možná dokázali odvodit z předchozích textů. Funkce by měla mít nějaký popisný název, který však bude rozumě dlouhý. Název by měl odpovídat tomu, co funkce dělá, a funkce by měla dělat pouze tu věc, kterou má napsanou v názvu. Pokud například funkce získává data z nějakého zdroje, neměla by při tom něco nastavovat. Podívejte se na příklad:

class Kosik:
    ...
    def pridatDoKosiku( self, produkt ):
        self.vyprazdnitKosik()
        self.kosik.append( produkt )
        return self.kosik
    ...

Asi byste podle názvu tipovali, že metoda přidá do košíku výrobek a popřípadě vrátí logickou hodnotu, zda se to povedlo či nikoliv. Možná si to myslíte, ale metoda vás pěkně obelstí, protože před přidáním celý košík vyprázdní a ještě k tomu vrátí obsah košíku. Takovou hrůzu by asi nikdo nenapsal (autor je optimista – pozn.red.), ale je spousta funkcí, které dělají velmi neočekávané věci – a to je špatně!

Vyvarovat se psaní funkcí, které dělají věci navíc, lze třeba tím, že se budeme držet dalšího pravidla: Pište funkce malé. Pokud budeme psát malé (krátké) funkce, tak se nám nestane, že bychom napsali funkci, která dělá spoustu dalších, nečekaných, věcí. Funkce by měla dělat jen jednu věc a dělat ji řádně – a to zvládne spíš malá funkce. Z vlastní zkušenosti mohu říci, že dlouhé funkce jsou náchylnější na chyby než ty krátké, a daný úkol nezvládají dělat dobře.

def ziskatAkcie( symbol='GOOG' ):
    url = urllib.urlopen( 'http ://download.finance.yahoo.com/d/quotes.csv?s=%s&f=nl1c1' % symbol )
    data = url.read()
    akcie = data.split( ',' )
    nazevSpolecnosti = akcie[0].split( '"' )[1]
    posledniObchod = akcie[1]
    zmena = akcie[2]
    return {
        'nazevSpolecnosti' : nazevSpolecnosti,
        'posledniObchod' : posledniObchod,
        'zmena' : zmena,
    }

Určitě vidíte, co je špatně: I když funkce dělá, co se od ní očekává, stejně provádí nějaké operace navíc. Lepší by bylo určité činnosti rozdělit do menších funkcí/metod, zhruba následujícím způsobem (metody zde rozepisovat nebudu, to není pro ukázku důležité).

class Kurzy:
    ...
    def ziskatKurz( self, symbol ):
        self.nastavitSymbol( symbol )
        self.ziskatData()
        self.parsovatKurz()
        return self.kurz
    ...

Dalším dobrým pravidlem je, že funkce by měla mít co nejméně argumentů. Ideální jsou funkce, které mají dva a méně argumentů. Pokud má vaše funkce více argumentů než např. pět, je na místě se zamyslet, zda to je v pořádku a zda to nelze udělat lépe. Může ovšem nastat situace, kdy je nutné tyto argumenty předávat – pak zvažte, zda skupinu argumentů nebude vhodnější předávat jako objekt. Příkladem může být předávání souřadnic.

vykresliKouli( x, y, z, r )

bod = Bod( x, y, z )
vykresliKouli( bod, polomer )

Závěr

Z dnešního dílu by měla být jasná následující pravidla:

  • Názvy by měly být popisné.
  • Používejte konstanty.
  • Funkce by měly být krátké.
  • Funkce by měly dělat jednu věc a pořádně.
  • Funkce by měly mít co nejméně argumentů.

Příště se podíváme na objekty, komentáře a formátování.

Poznámka redakce: U pravidel pro psaní „hezkého kódu“ platí snad víc než kde jinde zlaté ponaučení o uměřenosti: Každé pravidlo musí být důsledně aplikováno vždy a všude, pokud je to v rozumné míře. Právě pravidla „hezkého kódu“ ráda sklouzávají v praxi do dogmatických výkladů, kdy se z nich stává spíš noční můra kodérů. Pravidla uvedená v článku jsou obecně platná, ale pokud zrovna ve vaší firmě máte jiná, jistě je máte z dobrého důvodu. 

Školení Google+ pro firmy

DW - Školení PPC
  • Jak využít Google+ pro firemní komunikaci a marketing.
  • Čím se liší Google+ od Twitteru a Facebooku z pohledu firemního využití.
  • Jak využít Google+ v souladu s pravidly užívání.
  • Založení Google+ Page (Stránky) krok po kroku, včetně praktických tipů.

Detailní informace o školení Google+ »

Přehled názorů

Poznámky redakce v těle článku
Makovec 13. 4. 2010 00:54
Nový
├ 
Re: Poznámky redakce v těle článku
iki 13. 4. 2010 06:34
Nový
│
└ 
Re: Poznámky redakce v těle článku
Martin Malý 13. 4. 2010 09:04
Nový
│
 
└ 
Re: Poznámky redakce v těle článku
Michal Hořejšek 13. 4. 2010 16:26
Nový
└ 
Re: Poznámky redakce v těle článku
ahl 13. 4. 2010 08:35
Nový
 
└ 
Re: Poznámky redakce v těle článku
Martin Malý 13. 4. 2010 09:08
Nový
 
 
├ 
Re: Poznámky redakce v těle článku
ahl 13. 4. 2010 09:57
Nový
 
 
└ 
Re: Poznámky redakce v těle článku
ahl 13. 4. 2010 15:44
Nový
čeština v kódu
Aleš Roubíček 13. 4. 2010 07:37
Nový
├ 
Re: čeština v kódu
Honza Vrana 13. 4. 2010 07:58
Nový
│
├ 
Re: čeština v kódu
neron 13. 4. 2010 08:16
Nový
│
│
├ 
Re: čeština v kódu
ahl 13. 4. 2010 08:32
Nový
│
│
│
└ 
Re: čeština v kódu
neron 13. 4. 2010 08:37
Nový
│
│
└ 
Re: čeština v kódu
Aleš Roubíček 13. 4. 2010 08:36
Nový
│
│
 
├ 
Re: čeština v kódu
alejo 13. 4. 2010 09:09
Nový
│
│
 
│
├ 
Re: čeština v kódu
Aleš Roubíček 13. 4. 2010 09:58
Nový
│
│
 
│
└ 
Re: čeština v kódu
s 15. 4. 2010 21:52
Nový
│
│
 
│
 
└ 
Dokonalý kód
Franta Kučera 15. 4. 2010 22:09
Nový
│
│
 
│
 
 
└ 
Re: Dokonalý kód
petan 22. 4. 2010 11:06
Nový
│
│
 
└ 
Re: čeština v kódu
Franta Kučera 13. 4. 2010 10:49
Nový
│
│
 
 
└ 
Re: čeština v kódu
Aleš Roubíček 13. 4. 2010 10:57
Nový
│
├ 
Re: čeština v kódu
Martin Kubát 13. 4. 2010 08:35
Nový
│
│
└ 
Re: čeština v kódu
uf 14. 4. 2010 08:41
Nový
│
├ 
Re: čeština v kódu
Aleš Roubíček 13. 4. 2010 08:40
Nový
│
├ 
Re: čeština v kódu
Murděj Uktrurný 13. 4. 2010 08:50
Nový
│
│
└ 
Re: čeština v kódu
uf 14. 4. 2010 08:44
Nový
│
└ 
Re: čeština v kódu
s 15. 4. 2010 21:44
Nový
├ 
Re: čeština v kódu
Franta Kučera 13. 4. 2010 10:39
Nový
│
├ 
Re: čeština v kódu
Aleš Roubíček 13. 4. 2010 10:50
Nový
│
│
├ 
Re: čeština v kódu
Martin Malý 13. 4. 2010 10:57
Nový
│
│
└ 
Re: čeština v kódu
Franta Kučera 13. 4. 2010 11:26
Nový
│
│
 
└ 
Re: čeština v kódu
Aleš Roubíček 13. 4. 2010 13:02
Nový
│
│
 
 
└ 
Re: čeština v kódu
Franta Kučera 13. 4. 2010 13:26
Nový
│
├ 
Re: čeština v kódu
Petr Krontorad 13. 4. 2010 11:48
Nový
│
└ 
Re: čeština v kódu
Jiří Knesl 16. 4. 2010 07:02
Nový
│
 
└ 
Re: čeština v kódu
Franta Kučera 16. 4. 2010 13:43
Nový
│
 
 
└ 
Re: čeština v kódu
Jiří Knesl 16. 4. 2010 14:24
Nový
│
 
 
 
└ 
Re: čeština v kódu & OpenUP
Franta Kučera 19. 4. 2010 22:47
Nový
└ 
Re: čeština v kódu
bzuK 19. 4. 2010 17:02
Nový
 
└ 
Re: čeština v kódu
Aleš Roubíček 19. 4. 2010 17:17
Nový
 
 
└ 
Re: čeština v kódu
bzuK 19. 4. 2010 18:24
Nový
 
 
 
├ 
Re: čeština v kódu
Franta Kučera 19. 4. 2010 18:37
Nový
 
 
 
└ 
Re: čeština v kódu
uf 20. 4. 2010 11:37
Nový
 
 
 
 
└ 
Re: čeština v kódu
uf 20. 4. 2010 11:39
Nový
Testovanie
Štefan Ľupták 13. 4. 2010 08:41
Nový
├ 
Re: Testovanie
Aleš Roubíček 13. 4. 2010 10:00
Nový
├ 
Re: Testovanie
Michal Hořejšek 13. 4. 2010 16:29
Nový
└ 
Re: Testovanie
uf 14. 4. 2010 08:47
Nový
Čistý kód
mila 13. 4. 2010 11:09
Nový
└ 
Re: Čistý kód
uf 14. 4. 2010 08:50
Nový
Vsetko v pohode ale 2100 nie je presutpny rok.
Kacer 13. 4. 2010 12:21
Nový
└ 
Re: Vsetko v pohode ale 2100 nie je presutpny rok.
Martin Malý 13. 4. 2010 15:07
Nový
 
└ 
Re: Vsetko v pohode ale 2100 nie je presutpny rok.
Kacer 13. 4. 2010 17:52
Nový
 
 
└ 
Re: Vsetko v pohode ale 2100 nie je presutpny rok.
Míša Hájková 15. 4. 2010 15:42
Nový
python pel
jan krcmar 13. 4. 2010 13:18
Nový
└ 
Re: python pel
kodér 13. 4. 2010 20:27
Nový
 
└ 
Re: python pel
Pavel Lang 13. 4. 2010 22:50
Nový
Přestupný rok
xx 13. 4. 2010 15:00
Nový
└ 
Re: Přestupný rok
Martin Malý 13. 4. 2010 15:06
Nový
 
├ 
Re: Přestupný rok
xx 13. 4. 2010 15:17
Nový
 
│
├ 
Re: Přestupný rok
Martin Malý 13. 4. 2010 15:29
Nový
 
│
└ 
Re: Přestupný rok
Michal Hořejšek 13. 4. 2010 16:09
Nový
 
│
 
├ 
Re: Přestupný rok
Aleš Roubíček 13. 4. 2010 16:35
Nový
 
│
 
│
└ 
Re: Přestupný rok
Honza Kral 13. 4. 2010 16:49
Nový
 
│
 
│
 
└ 
Re: Přestupný rok
Aleš Roubíček 13. 4. 2010 17:38
Nový
 
│
 
└ 
Re: Přestupný rok
mciha 14. 4. 2010 11:14
Nový
 
└ 
Re: Přestupný rok
uf 14. 4. 2010 08:54
Nový
Osetrovani chyb a poznamky k pythonu
Honza Kral 13. 4. 2010 15:04
Nový
├ 
Re: Osetrovani chyb a poznamky k pythonu
Martin Malý 13. 4. 2010 15:23
Nový
│
└ 
Re: Osetrovani chyb a poznamky k pythonu
Honza Kral 13. 4. 2010 15:35
Nový
│
 
├ 
Re: Osetrovani chyb a poznamky k pythonu
Martin Malý 13. 4. 2010 15:42
Nový
│
 
└ 
Re: Osetrovani chyb a poznamky k pythonu
uf 14. 4. 2010 10:04
Nový
└ 
Re: Osetrovani chyb a poznamky k pythonu
Michal Hořejšek 13. 4. 2010 16:23
Nový
 
├ 
Re: Osetrovani chyb a poznamky k pythonu
Pavel Lang 13. 4. 2010 23:07
Nový
 
└ 
Re: Osetrovani chyb a poznamky k pythonu
che 14. 4. 2010 01:35
Nový
Jistě, ale
Tupčík 13. 4. 2010 21:15
Nový
├ 
Vývojářská dokumentace
Franta Kučera 13. 4. 2010 22:29
Nový
│
└ 
Re: Vývojářská dokumentace
Pavel Lang 13. 4. 2010 23:10
Nový
│
 
└ 
Re: Vývojářská dokumentace
Franta Kučera 13. 4. 2010 23:37
Nový
│
 
 
└ 
Re: Vývojářská dokumentace
Tupčík 14. 4. 2010 11:34
Nový
│
 
 
 
└ 
Re: Vývojářská dokumentace
Pavel Lang 14. 4. 2010 12:51
Nový
│
 
 
 
 
└ 
Re: Vývojářská dokumentace
Tupčík 15. 4. 2010 14:36
Nový
│
 
 
 
 
 
└ 
Re: Vývojářská dokumentace
Pavel Lang 15. 4. 2010 14:59
Nový
│
 
 
 
 
 
 
└ 
Re: Vývojářská dokumentace
Tupčík 15. 4. 2010 15:08
Nový
│
 
 
 
 
 
 
 
└ 
Re: Vývojářská dokumentace
Pavel Lang 15. 4. 2010 15:43
Nový
│
 
 
 
 
 
 
 
 
└ 
Re: Vývojářská dokumentace
Tupčík 15. 4. 2010 20:14
Nový
│
 
 
 
 
 
 
 
 
 
└ 
Re: Vývojářská dokumentace
Aleš Roubíček 16. 4. 2010 15:37
Nový
├ 
Re: Jistě, ale
Michal Augustýn 14. 4. 2010 07:53
Nový
│
└ 
Re: Jistě, ale
Tupčík 14. 4. 2010 11:36
Nový
└ 
Re: Jistě, ale
martin.mayer 15. 4. 2010 14:04
Nový
 
└ 
Re: Jistě, ale
Tupčík 15. 4. 2010 14:37
Nový
 
 
└ 
Re: Jistě, ale
Oldis 20. 4. 2010 09:43
Nový
       

Tento text je již více než dva měsíce starý. Chcete-li na něj reagovat v diskusi, pravděpodobně vám již nikdo neodpoví. Pro řešení aktuálních problémů doporučujeme využít naše diskusní fórum.

Zasílat nově přidané příspěvky e-mailem