Dobré praktiky

Dobré praktiky při vývoji software

Abychom minimalizovali vlastní chybovost při vývoji software, abychom mohli lépe vzájemně spolupracovat na společných software projektech, abychom rozuměli vlastnímu i cizímu kódu nyní i za léta, abychom byly efektivnější při práci, abychom uživatelům našeho software nabídli lepší zážitek, je dobré se při vývoji držet dobrých praktik.

1 Typografie

1.1 Základní pravidla

  • dostatek běžného textu
  • členěný a strukturovaný obsah bez dlouhých odstavců
  • jeden hlavní nadpis, další podnadpisy strukturovaně
  • nekombinovat mnoho písem, ideálně dvě
  • klávesa ENTER zásadně pro vytvoření nového odstavce, nadpisu, bloku
  • mezerník pro vytváření mezer mezi slovy, ne k odsazování
  • bez tabelátoru
  • zarovnání do bloku provětší texty
  • do webového WYSIWYG editoru text bez formátování
  • Obecně by se měl text jen zarovnat do odstavců, seznamů, nadpisů, citací a dalších prvků. Vše ostatní jako velikost písma, typ písma, barva, odsazení a podobně by mělo být formátováno šablonou webové stránky.

1.2 Předložky

Jedno hláskové neslabičné předložky K, k, S, s, V, v, Z, z, slabičné O, o, U, u, a spojky I, i, A, by neměly být na konci řádky. Výjimku tvoří spojka a. Abychom toho docílili na webu, je potřeba svázat danou předložku s podstatným jménem tzv. nedělitelnou mezerou, která se zapisuje v HTML jako  . Běžný mezerník toto nedocílí. U některých editorů k tomu stačí kombinace tlačítek SHIFT+CTRL+SPACE.

1.3 Zkratky

Zkratky slov, výrazů akademických titulů apod. se používají jen u vžitých výrazů a většinou končí tečkou. Ta se sází těsně za zkratkou (aj., apod., atd., DrSc., CSc.). Následuje-li za zkratkovou tečkou dvojtečka, sází se také bez mezery, přímo za tečku. U spojených zkratek se sází zúžená mezislovní mezera. Na začátku věty se spojená zkratka nahrazuje celým výrazem. Iniciálové zkratky (tj. zkratky z velkých počátečních písem spojených slov názvů, organizací a různých institucí) se sázejí verzálkami bez tečky (OSN, NATO, OPEC, ODS, ČR).

1.4 Čísla

Nižší číselné údaje se vyjadřují v sazbě slovně. Výjimku tvoří pouze letopočty, data a spojení čísel se zkratkami (100 m, 50 mm). Pozor na zápisy jednotek: 2 m (dva metry) vs. 2m (dvoumetrový).

1.5 Telefonní čísla

Telefonní čísla sázejí se ve skupinách po 2 – 3 číslech. Zásadně se nesmějí dělit do dvou řádek. V současnosti je vhodné dělit telefonní čísla po trojicích: +420 123 456 789.

1.6 Datum

Den je vždy vyjádřen arabskou číslicí, měsíc buď slovně, nebo arabskou či římskou číslicí s tečkou, letopočet se zásadně sází, bez vynechávání prvního dvojčíslí, výjimku tvoří pouze určitá spojení (Nagano 98). Datum vyjádřené pouze čísly se nesmí dělit do dvou řádek (30. 7. 2016). Tečka se píše hned za číslici následovaná mezerou.

1.7 Čas

Hodiny a minuty jsou od sebe odděleny tečkou bez mezer (12.00 hodin). Sekundy se oddělují od minut dvojtečkou, desetiny sekund od celých sekund čárkou (19:26,3 min.). U sportovních výkonů vyjádřených časem se hodiny od minut a minuty od sekund oddělují dvojtečkou (18:56:13 hodin).

1.8 Peněžní hodnoty

Značky peněžních měn Kč (Kč většinou až za číslo sumy), € apod. se sázejí před číslo sumy, je-li vedeno s desetinným číslem. Pokud je číslo celé, klade se značka měny za číselné označení nebo se dává před označení celých peněžních částek s desetinou čárkou a pomlčkou. (15,20 Kč; Kč 15,20; 500 Kč)

1.9 Zakončení vět a souvětí

Věty se zakončují tečkou, v souvětích pak čárkou. Tečka nebo čárka se píše hned za poslední slovo věty a je následovaná mezerou.

1.10 Dvojtečky

Dvojtečka se píše hned za slovo a je následovaná mezerou.

1.11 Špatný příklad

Přednáška s názvem základy typografie konaná 26.07.2021 trvala 2 hodiny. Začátek byl v 8:00h , ale někteří studenti přišli později. Naučili jsme se : základní pojmy, druhy fontů , hladkou sazbu. Cena školení byla stanovena na 500,- Kč. Na další školení se můžete objednat na telefonu 123456789 u pana ING. Michala Bubílka.

1.12 Dobrý příklad

Přednáška s názvem Základy typografie konaná 26. 7. 2021 trvala dvě hodiny. Začátek byl v 8.00 hodin, ale někteří studenti přišli později. Naučili jsme se: základní pojmy, druhy fontů a hladkou sazbu. Cena školení byla stanovena na 500 Kč. Na další školení se můžete objednat na telefonu +420 123 456 789 u pana Ing. Michala Bubílka.

1.13 Proč řešit typografii?

Zdánlivě se mohou zdát pravidla typografie zbytečná, ale zabývat byste se jimi měli minimálně ze dvou důvodů:

  • Váš web nepůsobí amatérsky.
  • Návštěvníkům se typograficky korektní text čte lépe a to může být jeden malý důvod z mnoha dalších, proč by chtěl příště znovu Váš web navštívit.

2 Prostředí vývoje

2.1 Umístění projektu

Pracujeme-li ve Windows, tak projekt neumisťujeme ani na plochu ani do dalších uživatelských složek (dokumenty...). Ideálně si na nesystémovém disku D vytvoříme složku development nebo jen dev a v ní pak jednotlivé složky našich projektů. Toto můžeme pak jednoduše ještě dále strukturalizovat. Cesta k našemu projektu pak může vypadat například takto: D:\development\web_projects\library.

Takovéto složky zálohujeme na lokální cloud, napojíme na git atp...

2.2 Pojmenování souborů a adresářů (složek)

U názvů souborů a složek používáme jen znaky a-z, A-Z, 0-9, _ a -. Vyhneme se diakritice, mezerám a dalším speciálním znakům. Předejdeme tím tak problémům s různými souborovými systémy a například problémy s propojením složky na WAMP server.

Složky pojmenováváme standardně dle obsahu například app, src, www, js, css, libs...

U souborů dodržujeme standardní přípony například: html, js, php, py, c...

2.3 Adresářová struktura

Není dobré mít všechny zdrojové soubory v jedné složce. Struktura by měla být zřejmá. Některé technologie (composer, npm...) již pracují se zaběhlými strukturami, aby bylo například možné použít autoloader souborů.

Příklad struktury webové aplikace:

/project-name
— /.git
— /.vscode
— /src
  — /models
  — /views
  — /controllers
— /data
— /www
  — /img
  — /css
  — /js
  — /scss
— /vendor
— /test
— .htaccess
— conf.ini
— index.html
— README.md

2.4 Zálohujte

Jak říkával můj kamarád: "Lidé se dělí na ty, kteří nezálohují a na ty, kteří už zálohují."

Své práce zálohujte (často a pravidelně) na světové nebo své lokální cloudy (např. Synology). Ideálně použít službu GIT třeba na githubu. Nezálohujte si něco, co můžete kdykoliv stáhnout z oficiálních zdrojů (DBMS, IDE...).

3 Zdrojový kód

3.1 Pojmenovávání obecně

U názvu proměnných, konstant, tříd, metod atp obecně nepoužíváme diakritiku, mezery, čísla na začátku atp. Držíme se obvykle jen znaků a-z, A-Z, 0-9, _ a -. Něco nám nedovolí ani syntaxe jazyka. K pojmenovávání také obvykle používáme anglický jazyk, který je v IT obecně univerzálním komunikačním jazykem.

3.2 Název proměnné

Proměnné pojmenováváme stručně, ale ideálně tak, abychom již z názvu tušili, co je v ní uloženo. Pro víceslovné názvy používáme obvykle Camel Case např. selectedRows nebo minCircleRadius. Pro iterace používáme obvykle názvy i, j, k, pro obecná čísla nebo hodnoty souřadnic pak x, y, z, pro obecný počet pak n.

3.3 Název konstanty

Konstanty pojmenováváme kompletně velkými písmeny (Uppercase, Troll Case). Pro víceslovné názvy používáme obvykle Snake Case např. DB_PASSWORD nebo DEFAULT_APP_LANG

3.4 Název funkce

Funkce vykonávají nějaký sled operací. Ideálně je pojmenujme tak, aby z názvu bylo patrné, co funkce provádí např. clear_screen, případně co funkce vrací např. factorial. Pro víceslovné názvy se obvykle používá Camel Case např. getRadius případně Snake Case např. generate_table. Je vhodné si zvolit jednu notaci a tu používat v celém projektu. Preferuji Camel Case.

3.5 Název třídy nebo rozhraní

Pro názvy tříd se používá obvykle Pascal Case např. UserModel nebo HomePagePresenter. Je zvykem, že pro celou třídu je vytvořen právě jeden soubor, který se jmenuje stejně jako třída. Také je dobré nějak rozlišit interface již v názvu. Je běžné použít prefix I např. IAnimal nebo, pokud rozhraní vyjadřuje vlastnost (schopnost), pak např. Movable.

3.6 Název atributu

Název atributu tvoříme podobně, jako název proměnné. Používá se Camel Case. Měl by být samopopisný. Atribut se volá vždy z nějakého kontextu (třída, objekt), není tedy nutné, aby v jeho názvu byl název třídy atp... Bývá zvykem, abychom předešli chybnému obsahu, že se atribut nastaví na private a manipuluje se s ním pomocí metod.

3.7 Název metody

Metody manipulují s atributy a podobně jako atributy (proměnné) se tvoří i jejich název. Používá se Camel Case. Metody obvykle mění stav objektu, proto by měla být i z názvu patrná činnost např. clearMask nebo changeUser. Bývá zvykem vytvoření tzv. getterů (vrací hodnotu atributu) např. getRadius a setterů (nastavují hodnotu atributů) např. setRadius.

3.8 Počty řádků kódu

Špatně se pracuje s kódem, který má tisíce řádek, které jsou v jednom souboru nebo jen v bloku {}. Každý blok by tak měl mít do cca 30 řádek a soubor do cca 400-600 řádek. Pokud jich je více, je dobré se zamyslet nad restrukturalizací kódu. Každá funkce by měla řešit jen jednu svou problematiku.

3.9 Vnořování

Vnořování je prima, jen ho nesmí být přespříliš. Čtyři stupně jsou OK. U hlubšího zanořování je potřeba se již zamyslet nad restrukturalizací.

Mějme kód:

if(cond#1){
  if(cond#2){
    return true;
  }else{
    return false;
}else{
  return false;
}

Místo toho můžeme napsat toto:

if(!cond#1 && !cond#2){
  return false;
}
return true;

3.10 DRY

Zkratka DRY (Don't repeat yourself) míní, že není dobré, aby se ve zdrojovém kódu něco opakovalo. Opakovat se pak mohou i chyby. Opravit to nemusíme u všech výskytů. Kód je nepřehlednější a hůře se opravuje. Budeme-li chtít funkcionalitu zlepšit, musíme změnu zanést opět do všech výskytů. Pokud tedy začneme psát kód, který podobný jsme již v našem programu psali, bude vhodné použít např. cyklus nebo si na tento kód napsat vlastní funkci a tu již na patřičných místech jen volat. Programujeme tak více obecně, hromadně. Vytvořené funkce pak můžeme použít i v dalších jiných projektech (znovupoužitelnost).

3.11 KISS

"Keep It Simple, Stupid!" neboli "Zachovej to jednoduché, hlupáku!" Toto pravidlo říká, že je dobré udržovat kód jednoduchý a tím i dobře pochopitelný. Není vždy dobré optimalizovat kód na počty řádků a vymýšlet komplikované zkratky. Čemu porozumíte rychleji? Tomuto:

return x>0?fce(x):(x<0?fce(-x)/2:0);

nebo tomuto:

result = 0;
if(x>0){
  result = fce(x);
}else if(x<0){
  result = fce(-x)/2;
}
return result;

3.12 Komentáře

Nezapomínejme si některé důležité části kódu komentovat. Rychleji si tak pro příště připomeneme, jak daná funkce pracuje. Každý jazyk komentáře podporuje. Obvykle se jedná o řádkové komentáře // ... nebo blokové komentáře /* ... */.

3.13 Dokumentační komentáře

V OOP je zvykem komentovat třídy, atributy a metody. Používají se k tomu speciální dokumentační komentáře /** ... */, které mají svá speciální pravidla. Můžeme přesně uvést základní popis třídy (metody i atriburtu), parametry funkce @param, typ návratové hodnoty @return, autora třídy @author a mnoho dalšího. Tyto komentáře jsou pak používány k napovídání při psaní kódu v IDE a také se z nich dá mnohdy vygenerovat dokumentace pro API.

3.14 YAGNI

YAGNI neboli "You aren't gonna need it" značí, že není třeba psát kód na něco, co by možná mohlo být potřeba. Zbytečně tak vytváříme prostor pro další chyby. Programujme jen to, co je potřeba. Podobně platí i princip "Neopravuj, co není rozbité".

3.15 Buďte obezřetní

Pište kód tak, jako byste očekávali to nejhorší. Předpokládejte všechny varianty, které Vám mohou uživatelé zadávat na vstupu. Předpokládejte pády systémů.

3.16 Build & Fix

Zadaný problém rozdělíme na mnoho menších problémů (Divide and conquer), které lze psát postupně. Každou část tak po vytvoření otestujeme, zbavíme chyb a poté pokračujeme dál.

3.17 Testujeme

Nejprve zajistíme funkčnost kódu. Tedy, řeší-li to, co bylo v zadání. Poté optimalizujeme na výkon. Každou fázi je dobré testovat. Pro testování je dobré používat automatické Unit testy, které si píšeme průběžně se vznikajícím kódem.

4 Databáze

4.1 Pojmenovávání databáze

Pro název databáze je dobré dodržovat standardní praktiky pojmenovávání. U názvu databáze tedy použijeme angličtinu, Lowercase (malými písmeny), bez diakritiky základními znaky s použitím Snake Case např. library, elite_crm, world_cms...

4.2 Pojmenovávání tabulek

Tabulky (entitní typy) pojmenováváme anglicky, Lowercase (malými písmeny), bez diakritiky základními znaky s použitím Snake Case např. movie, genre, movie_has_genre... Jedná se o podstatná jména, kde se vede u mnohých vývojářů boj o to, má-li to být jednotné nebo množné číslo. Mé doporučení je jednotné číslo, které přináší méně problémů s podivnými tvary slov a přirozenější užití u ORM. Na druhou stranu množná čísla lépe vystihují obsah tabulky a jsou méně náchylná na konflikty s klíčovými slovy.

4.3 Pojmenovávání atributů

Pro atributy (vlastnosti záznamů, sloupce tabulek) používáme podobná pravidla, jako u databází a tabulek, tedy angličtina, Lowercase, Snake Case např. id, name, full_name... Nepoužíváme prefix s názvem tabulky. V  případě, že použijeme zápis i s názvem tabulky např. movie.name, je vše jasné a přehledné.

4.4 Primární klíče

Primární klíč jsou nejčastěji jeden číselný sloupec tabulky. Ideální je tedy jej pojmenovat id a nastavit mu UN a AI. Později to oceníte ve zdrojovém kódu programu při použití s ORM. Je zbytečné používat prefix s názvem tabulky, v SQL zase můžete použít i název tabulky movie.id, což stačí a vypadá lépe než movie.movie_id.

U M:N vztahových tabulek je pak primární klíč n-ticí cizích klíčů, které je vhodné pojmenovávat např. movie_id a genre_id v tabulce movie_has_genre

4.5 Cizí klíče

Cizí klíč slouží nejčastěji pro 1:N a M:N vztahy a je primárním v jiné (cizí) tabulce. Proto je vhodné u něj naopak cizí tabulku uvést. V tabulce movies pak bude cizí klíč country_id. Hned je pak z názvu zřejmé, že se jedná o cizí klíč, který odkazuje na záznamy v tabulce country.

4.6 SQL dotazy

Pro lepší přehlednost v SQL dotazech je dobré klíčová slova psát velkými písmeny (Uppercase) a jednotlivé části dotazu psát na nové řádky.

SELECT movie.*
FROM movie
  JOIN genre ON genre_id = genre.id
WHERE genre.id IN(1, 3, 8)
ORDER BY movie.year DESC
LIMIT 10