10. diel - Najčastejšie chyby C# nováčikov - Vieš pomenovať premenné?
V predchádzajúcom cvičení, Riešené úlohy k 8.-9. lekcii C# .NET, sme si precvičili získané skúsenosti z predchádzajúcich lekcií.
V dnešnom tutoriáli C# .NET si ukážeme prvé tzv. dobré praktiky pre programovanie v C# .NET. Často ich porušujú nielen nováčikovia a programátori tak zanášajú do svojich programov zbytočné chyby. Nerobíš ich tiež?
Slovo senior programátora

Gratulujem k zdolaniu prvých lekcií Základných konštrukcií jazyka C# .NET!
Materiál dnešnej lekcie som zostavil na základe dvadsiatich rokov skúseností s programovaním. Ako šéfredaktorovi a lektorovi mi rukami prešli stovky, možno tisíce zdrojových kódov vytvorených komunitou. Nebolo ťažké si všimnúť, že hoci väčšina týchto kódov funguje, obsahuje zbytočné chyby, ktoré sa navyše stále dookola opakujú. Chyby prekvapivo často robili ako nováčikovia, tak skúsenejší programátori. Medzi chybujúcich som v začiatkoch patril aj ja.
Došiel som k tomu, že základným a mylným predpokladom je:
✗ Program je správny, ak funguje.
Programy a domy
Ak staviame dom, tak to, že sa nám páči a nefúka do neho, neznamená, že je postavený správne. Dom totiž musí mať premyslenú architektúru, a ak nemá základy, o pár rokov sa nám začne zosúvať.
Programovanie je často prirovnávané k stavebníctvu práve s ohľadom na architektúru, v našom prípade však tú softvérovú. Vysvetlime si prečo.
Ľudský mozog dokáže naraz pracovať len s určitým obmedzeným množstvom informácií. Zjednodušene môžeme povedať, že pokiaľ je program napísaný neprehľadne, od určitej chvíle musel programátor udržať v hlave viac vecí, než človek vôbec dokáže. Pridávanie ďalších funkcií do takého programu potom vždy spôsobí, že v aplikácii vznikne chyba. V praxi to dopadá tak, že hobby projekt autora "prestane baviť" a komerčný projekt skrachuje, pretože je už "veľmi zložitý".
Uveďme si ešte iný príklad. Keď bude naša domácnosť usporiadaná tak, že kladivo bude v lekárničke, ktorá bude umiestnená v pivnici, asi ťažko s ňou budeme schopní efektívne fungovať. Hoci tento príklad znie absurdne, jeho alternatívy v podobe programov vznikajú denne.
Kedy je program správny?
To je jednoduché. Program je správny, ak:
- funguje,
- dodržiava dobré praktiky a
- je otestovaný.
Všimnime si, že funkcionalita z pohľadu užívateľa programu predstavuje len 1/3 kritérií kvality programu. Podobne ako funkčnosť domu z pohľadu bývajúceho predstavuje asi iba zlomok jeho reálnej kvality z hľadiska stavbariny.
Dnes sa budeme baviť práve o porušovaní dobrých praktík a kvalite kódu. Záleží nám na tom, aby ste boli naozaj dobrí, preto takéto lekcie nájdete naprieč našimi kurzami viacero.
Ako správne pomenovať premenné?
Hovorí sa, že 10 % času niečo programujeme a 90 % času pre to
vymýšľame názov
Ide
samozrejme o nadsádzku, ale vtip naráža na nutnosť stráviť určitý čas
vymýšľaním názvov premenných. To, aby každý vrátane nás, kto sa po
pár mesiacoch vracia k vlastnému kódu, pochopil, na čo daná premenná
slúži. Všeobecne sa dá spoľahnúť na jednoduché pravidlo:
Premenné vždy pomenovávame podľa toho, čo obsahujú, nie podľa toho, na čo v programe slúžia.
Porovnajme nasledujúce 2 kódy:
✗ Chyba
string listing, text2; int[] array; int foo, bar, x, calculation;
✓ Správne
string title, name; int[] answers; int i, j, bonus, totalBonus;
Oba kódy vytvárajú premenné pre jednoduchý konzolový kvíz. Pri prvom
príklade nie je vôbec jasné, čo niektoré premenné obsahujú, napr.
pomenovať premennú array má asi rovnakú výpovednú hodnotu,
ako keby sme ju pomenovali variable.
Častou chybou tiež je, že chceme napr. uložiť výsledok
nejakého výpočtu a premennú pomenujeme
calculation. Výpočet s premennou však vôbec nesúvisí, to je
nejaká akcia (dej), premenná vždy obsahuje
hodnotu (výsledok deja). Tou je tu v prípade kvízu
totalBonus. Podobne je v prvom kóde pomenovaná premenná
extract, pretože ju niekde vypisujeme. Z druhého kódu ale
reálne vidíme, že obsahuje názov kvízu.
Ruku na srdce - kto z vás by pochopil, že kód vľavo sa týka programu na kvízy?
Premenné tiež nikdy nepomenovávame auxiliary
alebo aux a pod.
Pozor na mixovanie jazykov a diakritiku
V zdrojovom kóde je na našej začiatočníckej úrovni jedno, akým jazykom budeme premenné pomenovávať (pokiaľ teda nepošleme Angličanovi kód v slovenčine).
Premenné v jednom projekte pomenovávame jedným jazykom. Ak pomenovávame po slovensky, tak bez diakritiky!
Opäť si ukážme príklady:
✗ Chyba
string message = "Čau!"; int počet;
✓ Správne
String message = "Hi!"; int count;
Alebo:
String sprava = "Čau!"; int pocet;
V identifikátoroch (napr. v názvoch premenných) nikdy nepoužívame háčiky ani čiarky. V hodnotách v nich uložených je to už samozrejme v poriadku.
Napriek tomu, že moderné jazyky podporujú kódovanie UTF-8 aj v identifikátoroch, možno veľmi ľahko na háčik alebo čiarku zabudnúť a používame potom inú premennú! Navyše súbor so zdrojovým kódom môže spracovávať aplikácia, ktorá ho nepodporuje, čo sa typicky aj časom stane (napr. je občas problém zobraziť diakritiku v prílohe mailovým klientom a pod.).
Viacslovné premenné
Dnešné aplikácie sú čoraz zložitejšie. Často sa stane, že by jedno
slovo na opis toho, čo je v premennej uložené, nestačilo. Potom je výhodné
použiť viac slov. Krátke identifikátory z 80. rokov tak v súčasných
business aplikáciách striedajú aj pomerne dlhé názvy ako
userObjectOutputStreamFactory a podobne.
Takto dlhý názov má však zmysel iba v zložitej
aplikácii, kde je niekoľko podobných premenných, a preto musíme pridať
ďalšie slovo. Nebudeme teda v aplikácii Hello world vytvárať premennú
textWithGreetingsHelloWorld, ale stačí nám len
greeting, pokiaľ tam iný nie je 
Oddelenie slov
Kvôli čitateľnosti musíme slová v takom názve premennej nejako oddeliť:
- Viac slov oddeľujeme podľa konvencie daného programovacieho jazyka. V
prípade C# ide o tzv.
camelCase(slovensky ťavie notácie, kedy každé ďalšie slovo začína veľkým písmenom a názov potom vyzerá ako hrby). V iných jazykoch sa môže používať napr. podčiarknutie akosnake_casea ďalšie notácie. - Ak je to možné, vyhneme sa číslovaniu premenných a už vôbec
nepíšeme čísla slovami, nie
greeting2anigreetingsTwo. "Two" totiž nehovorí nič o tom, čo pozdrav obsahuje.
Ukážme si to na príkladoch:
✗ Chyba
string message1; string messageTwo;
Tu nie je jasné, čo je uložené:
string received; // text, bytes, message, order...? string sent;
A tu je názov nečitateľný:
string receivedmessage; string sentmessage;
✓ Správne
string receivedMessage; string sentMessage;
Nepoužívame skratky
Túto podkapitolu začnime citáciou:
Všetci si lámali hlavu nad tým, na čo je ten stĺpec
DATBIR. Až sa raz zistilo, že je to vraj dátum narodenia (date of birth).
Táto zlá praktika je vlastne opakom viacslovných názvov premenných.
Nevymýšľame nezmyselné skratky, napríklad z názvu rm nikto
nespozná, že myslíme receivedMessage. Pomôcka môže byť:
Ak sa na kód pozrie niekto iný ako my, mal by presne vedieť, čo v ktorej premennej je.
✗ Chyba
string ms; int nm;
✓ Správne
string message; int numberOfMessages;
Ako sme sľúbili, k téme dobrých praktík sa ešte niekoľkokrát vrátime
v podobných, skôr oddýchových lekciách 
V ďalšej lekcii, Textové reťazce v C# druhýkrát - Práca s jednotlivými znakmi, na vás čaká prekvapenie 

David sa informačné technológie naučil na