27. diel - Najčastejšie chyby C# nováčikov - Vieš pomenovať objekty?
V predchádzajúcej lekcii, Záznamy v C# .NET, sme si predstavili referenčný typ záznamy zabudovaný v .NET frameworku.
V dnešnej lekcii C# .NET OOP si ukážeme prvé dobré praktiky pre objektovo orientované programovanie v C# .NET. Pozri sa, či nerobíš jednu z najčastejších chýb.
Slovo senior programátora

Gratulujem k zdolaniu základnej problematiky objektovo orientovaného programovania! 🏆 Dostal si sa k záchytnému bodu, pri ktorom sa trochu vydýchame a ukážeme si, ako správne použiť nadobudnuté informácie skôr, ako sa pustíme do ďalších. Materiál pre dnešnú lekciu som zostavil na základe 20-ročných skúseností s programovaním a jej obsah bude mať zásadný vplyv na tvoje ohodnotenie na trhu práce.
Miliónové straty
O dobrých praktikách sme sa už bavili v kurze Základné konštrukcie jazyka C#. NET a vieme, že neprehľadné programy nie sú vôbec žiadna malichernosť. Sú totiž:
- Nezrozumiteľné pre ostatných - Keď tím 5 programátorov, každý s platom 5.000 € mesačne, strávi 20 % pracovnej doby lúštením kódu, stojí to ročne 60.000 €!
- Náchylné na chyby - Tržby aj malých e-shopov sú mesačne zvyčajne v stovkách tisícoch eur. 1 deň nefunkčnosti teda stojí majiteľa desiatky tisíc eur, dodávateľovi hrozia nemalé zmluvné pokuty.
- Prakticky nerozšíriteľné - V súčasnej funkčnosti sa už nikto nevyzná a nemožno ju rozšíriť. Programátorský tím niekoľkých ľudí musí vytvoriť aplikáciu znova, sme opäť v stovkách tisícoch eur.
- Netestovateľné, nezabezpečené a takto by sme mohli pokračovať aj ďalej.
Niet pochýb, že dobré praktiky sú pre vývoj softvéru v tíme úplne zásadné a následky ich porušenia potom úplne fatálne.
Ako správne pomenovať triedy, atribúty a metódy?
Vieme vytvárať množstvo nových objektových konštrukcií, v programoch nám vzniká množstvo nových identifikátorov (mien). V dnešnej lekcii sa budeme zaoberať tým, ako "objektové súčiastky" našich aplikácií správne pomenovať, aby boli prehľadné.
Motivačný príklad
K doktorovi príde pacient a hovorí mu, že má problém so svojím orgánom
Move. Nefunguje mu Shoe. Pacient vyzerá byť nejaký
popletený a doktorovi trvá pomerne dlho, kým z neho dostane, že ho pichá v
päte, a preto si nemôže obuť topánku. Keď konečne pustí pacienta z
ordinácie, zistí, že bol súčasťou skupiny a takých ich tam ešte čaká
niekoľko desiatok.
Pozrime sa ešte na druhý príbeh. Programátorovi pridelí program, ktorý
spadne s chybou v triede MoveData, metóde Data().
Program je popletený a programátorovi trvá dlho, kým zistí, že sa jedná o
triedu importujúcu dáta z externej zálohy a že sa prvýkrát musí ručne
zavolať metóda Work(), ktorá import vykoná. Keď chybu konečne
opraví, objaví sa ďalšia a zistí, že v programe je niekoľko desiatok
tried a metód, z ktorých názvu vôbec nespozná, čo robia.
Určite vidíme paralelu týchto dvoch príbehov. Zatiaľ čo pri ľudskom tele by nás asi ťažko napadlo hovoriť o orgáne "Move" a metóde "Shoe", v programoch bohužiaľ nie je problém naraziť na objekty pomenované ako deje a funkcie pomenované ako veci, aj keď je princíp úplne rovnaký. Niet divu, že si Indescriptive naming vyslúžilo svoje miesto v šestici najhorších programátorských praktík STUPID.
Pomenovanie tried
Triedy definujú objekty, z ktorých je aplikácia zložená. Z toho vyplýva niekoľko triviálnych pravidiel. Názvy tried:
- sú podstatné mená! - Jedná sa o jednotlivé počítateľné objekty bez ohľadu na to, koľko objektov od triedy potom vytvoríme.
- nie sú názvy dejov - Ide o objekty (veci). Triedy teda
nemôžeme nazvať napr.
WorkWithFilealeboPrinting, ale napr.FileManageraleboPrinter(alebo ešte lepšieUserInterface, pretože zriedka tvoríme celú triedu len na vypísanie niečoho). - začínajú veľkým písmenom - Každé ďalšie slovo má
veľké písmeno (notácia)
PascalCase. Je tak vidno, že ide o všeobecnú triedu a nie o jej konkrétnu inštanciu. - sú pomenované podľa toho, akú súčasť programu reprezentujú - nemusí to byť vždy rovnaké, ako to, čo robia vo vnútri.
Ukážme si niekoľko príkladov:
✗ Chyba
class employee class Employees class Invoiceitem class WorkWithFile class Print class EnteringData
✔ Správne
class Employee class EmployeeManager class InvoiceItem class FileDatabase class UserInterface
Ak narazíte na program, kde sa trieda volá WorkWithFile, jeho
autor si pravdepodobne len vygooglil, že kód sa píše do class.
Netušil, že tým vytvoril nejaký objekt.
Triedy v množnom čísle
V množnom čísle pomenovávame triedy veľmi zriedka.
Napríklad v Jave takto nájdeme triedu Arrays. Od tej nevytvárame
inštancie a používame ju len na prácu s inštanciami triedy
Array, teda s poľami. Pole triedime napr. ako:
Arrays.sort(employees);
Osobne by mi oveľa väčší zmysel dávalo, aby tieto metódy mala na sebe
priamo trieda Array a písali sme teda:
employees.sort()
Autori Javy pravdepodobne nechceli, aby bola trieda Array
príliš zložitá, a tak pre niektoré metódy vytvorili túto druhú triedu.
Výsledný prínos je diskutabilný. My triedy v množnom čísle väčšinou
deklarovať nebudeme.
Pomenovanie tried v angličtine
Keď si doma programujete aplikáciu pre seba, môžete samozrejme používať slovenčinu. Kódy reálnych obchodných aplikácií sa ale píšu v angličtine. Pre anglické názvy tried platí samozrejme to isté, čo sme povedali vyššie. Môžeme však ľahko urobiť nasledujúce chyby:
- Jednotné čísla - Keď v slovenčine pomenujeme triedu
pracujúcu s autami
SpravcaAut, mohol by sa ponúkať anglický prekladCarsManager. Správne je všakCarManager, jednotné číslo, pretožeCartu funguje ako prídavné meno. - Poradie slov - Na rozdiel od slovenčiny je podstatné meno
na konci súslovia, správca áut teda nie je
ManagerCarsaleboManageCars, aleCarManager. Cesta k súboru nie jePathFile(čo by bol cestový súbor), aleFilePatha pod.
V angličtine sa pri triedach často používa koncovka -er,
napr. TaskRunner, podľa toho, čo trieda robí.
Ukážme si pár príkladov:
✗ Chyba
class CarsManager class PathFile class RunTasks
✔ Správne
class CarManager class FilePath class TaskRunner
Pomenovanie atribútov
Atribúty sú "premenné" danej triedy. Pre ich pomenovanie teda platia úplne tie isté zásady ako pre premenné, ktoré sme si už detailne vysvetľovali v lekcii Najčastejšie chyby C# nováčikov - Vieš pomenovať premenné?.
Základným pravidlom opäť je, že atribúty pomenovávame podľa toho, čo je v nich uložené. Názov atribútu chápeme v kontexte názvu triedy a nemusí teda dávať zmysel sám o sebe. Z jazykového hľadiska sú názvy atribútov:
- podstatné mená (
name,employees, ...), - prídavné mená (
disabled,sent, ...).
Pripomeňme si tu aj zvyšné zásady:
- všetky atribúty pomenovávame buď slovensky bez diakritiky alebo anglicky, ale nie kombináciou týchto jazykov,
- viacslovné atribúty pomenovávame pomocou notácie
camelCase, - ak atribút obsahuje kolekciu s viacerými hodnotami (napr. pole alebo
List), jeho názov je v množnom čísle.
Ukážme si opäť nejaké príklady názvov atribútov tried:
✗ Chyba
private string Name; private bool send; private string[] phonenumbers; private Button tlačidlo; private Address[] uzivatelAddress;
✔ Správne
private string name; private bool sent; private string[] phoneNumbers; private Button tlacidlo; private Address[] userAdresses;
Pomenovanie metód a parametrov
Metódy označujú deje, ich názov obsahuje teda sloveso ! Môže ísť o:
- prikazovací tvar (
LoadImages(),SetId()) - Metóda prevažne vykonáva nejakú činnosť a jej výsledok môže alebo nemusí vracať. Nevolíme infinitív alebo -ing tvar, napr.Loading(). - opytovací tvar - Metódou sa prevažne pýtame na nejakú
hodnotu predtým, ako by sme chceli vykonať nejakú akciu (slovensky napr.
VratMeno()aleboJeVypnuty()pre premenné typubool, anglicky napr.GetRank(). Už vieme, že takýmto metódam hovoríme gettery.
Metódy pomenovávame podľa toho, čo robia! Vyhýbame sa neurčitým
názvom ako Work(), Action(), Run() a
pod.
Ukážme si príklady:
✗ Chyba
public void Printing(Customer customer) public bool ReturnOn() private void Data() public void Work()
✔ Správne
public void PrintInfo(Customer customer) public bool IsEnabled() private void GenerateData() public void ImportBackup()
Parametre metód
Parameter metódy je premenná, a preto pre ich názvy
platia tie isté pravidlá, ako pre premenné a atribúty
(napríklad nikdy nepomenujeme parameter param
). Je tu však jedna dôležitá
vec, a to je použitie dvojitej negácie. Ukážme si posledný
príklad:
✗ Chyba
public void ImportData(bool disableForeignKeys = false)
✔ Správne
public void ImportData(bool enableForeignKeys = true)
Kto z vás dokáže povedať, či sú v prvom variante s odovzdaním hodnoty
false povolené kľúče? Všetko je zas o ľudskom mozgu, ktorý
nie je zvyknutý fungovať pod dvojitou negáciou. Volíme teda skôr
druhý variant.
V nasledujúcej lekcii, Ako správne rozdeliť C# .NET aplikácie do tried - SRP a SoC, si vysvetlíme dobré praktiky SRP (Single Responsibility Principle) a SoC (Separation of Concerns). Načrtneme aj tému závislostí.

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