Gratulujeme! Úspěšně jste se přihlásili k odběru novinek Frontend Garden.
Ajaj. Při pokusu o přihlášení k odběru novinek došlo k chybě. Zkuste to prosím znovu.
Frontend Garden
  • Články
  • Slovník nové
  • Instagram
  • GitHub
8. prosinec 2020 —
  • Kvalita kódu
— čtení na 10 min.

Jak zlepšit kvalitu kódu pomocí 5 jednoduchých principů

Dost už bylo špagety kódu. Vydejte se vstříc udržitelnosti a mějte své projekty na úrovni s využitím Software Design Principles. Název může znít vznešeně, ale nenechte se zmást. Nejedná se o nic jiného než aplikování selského rozumu v programování.

Kateřina Klouček Dlouhá

Kateřina Klouček Dlouhá

Katka je kodérkou od roku 2017. V současné chvíli pracuje jako Design System Architect. Oplývá entuziasmem pro vše, co souvisí s UX nebo typografií. Více o autorovi

Jak zlepšit kvalitu kódu pomocí 5 jednoduchých principů

V nedávném článku Hledá se kodér! Co vše by měl umět? jsme představili vyčerpávající soupis témat, která mohou souviset s prací frontend kodéra. Padla i zmínka o best practices, přesněji řečeno o softwarových návrhových principech jako KISS, DRY nebo YAGNI. V dnešním článku na tuto zmínku navážeme a povíme si o podstatě a aplikaci těchto principů.

Nemusíte se hrozit, že bychom zabíhali do detailů objektově orientovaného programování (s kterým návrhové principy úzce souvisí). Řeč bude o jednoduchých principech, které mnozí z vás aplikují v praxi, aniž by o tom věděli.

Kvalita kódu

Kódování, potažmo stylování, není vyšší dívčí, ale stejně jako vše ostatní, se dá dělat buď dobře, nebo špatně. Kde není čistý kód, nemůže být ani jeho vysoká kvalita.

Obecně lze tvrdit, že dobrý kód je takový, který:

  • dělá, co má,
  • je konzistentní,
  • je snadno pochopitelný,
  • je robustní,
  • má dobrou dokumentaci,
  • můžeme testovat,
  • neobsahuje legacy závislosti,
  • můžeme snadno udržovat a rozšiřovat,
  • nezanáší technický dluh.

Na kvalitní kód bychom neměli pohlížet jako na velkou vstupní investici s nejistou návratností. Dobrý kód má předem jasně danou návratovou hodnotu, která se projeví téměř ihned.

  • Urychluje orientaci v projektu, což uvítají především nováčci, ale i vývojáři, kteří se k projektu vrací po delší odmlce.
  • Minimalizuje technický dluh.
  • S rostoucím časem snižuje náklady spojené s údržbou a rozšiřováním projektu.
Je důležité si uvědomit, že kvalita kódu má zásadní dopad na kvalitu softwaru samotného.

Hodnotíme-li kvalitu kódu, nemůžeme vyvozovat závěry pouze na základě počtu metod či řádků, ze kterých se systém skládá. Ani z výsledků performance auditu. Hodnotí se celek jako takový. Je důležité si uvědomit, že kvalita kódu má zásadní dopad na kvalitu softwaru samotného – ovlivňuje i jeho úroveň zabezpečení, spolehlivost, výkon či použitelnost spjatou s prožitky vývojářů (Developer Experience, DX) a uživatelů (User Experience, UX).

Příklad kvalitativních metrik pro měření vlastností kódu

Základní principy

Ke kvalitnímu kódu může pomoci řada pouček. Mezi ně patří Software Design Principles. Jedná se o sadu doporučení, která by měl vývojář zužitkovat při práci. Pomocí těchto doporučení se nám daří psát kód čitelnější, robustnější, snáze udržitelný s možností jednoduchého rozšíření. Principy pomáhají předcházet mrtvému kódu, který mimo jiné zbytečně zabírá místo v repozitáři. Snižují duplicity a šetří tím práci při případném refactoringu. A především přispívají k menší frustraci nás, vývojářů.

Vzpomeňte si – kolikrát jste se vraceli k projektu, na který jste delší dobu nesáhli a při pohledu do kódu se vám div neprotočily panenky? Nebo jste potřebovali rozšířit o jeden řádek metodu, o které jste si mysleli, že se používá jen v daném místě, a rozbili jste tím půlku aplikace?

Díky návrhovým principům jsme schopni včas rozpoznat dobře napsaný projekt od pomalu tikajicí bomby.

Návrhové principy sice nejsou spásným řešením, které můžeme vždy dodržovat (záleží na případu užití, limitech pro časovou či paměťovou složitost, aj.). Rozhodně nás ale navedou správným směrem. Přehledný a udržitelný kód se bude psát takřka sám a navíc nás donutí se nad samotným kódem důkladněji zamyslet. Díky tomu budeme schopni včas rozpoznat dobře napsaný projekt od pomalu tikajicí bomby.

(Poznámka: Některé z níže uvedených principů jsou trochu vágní, takže nemůžeme s jistotou uvést všechny možné strategie a pravidla, které lze aplikovat. Vždy záleží na konkrétním případu užití.)

1. KISS

Název: Keep It Simple, Stupid (Nech to jednoduché, hlupáčku). Alternativně Short and Simple, Simple and Straightforward nebo Smart and Simple.

Myšlenka: Jednoduché řešení je lepší než komplexní, i když může vypadat primitivně.

Popis:

Vývojář se občas nechá svést na scestí používáním sofistikovaných a komplexních řešení, která na první pohled vypadají působivě. Tato volba může zapříčinit, že se kód těžko debuguje, rozšiřuje nebo vyžaduje více času na pochopení.

Nač si komplikovat život, když lze použít jednoduché, snadno pochopitelné a rychlé řešení? KISS si stojí za tím, že je lepší zbytečně se neuchylovat k dědičnosti, polymorfismu nebo třídám, pokud to není vyloženě nutné. Takové přístupy mohou přispět ke zesložitění kódu nebo vyšší provázanosti.

Jak na to:

  • Vyhněte se komplikovaným přístupům jako dědičnost nebo polymorfismus. Namísto toho upřednostněte jednoduché konstrukce if / else, v případě stylů pak třeba mixiny.
  • Vyvarujte se overengineeringu (přetechnizovanosti). V jednoduchosti je krása a v programování to platí dvojnásob.
  • Používejte co nejvýstižnější názvy, které jasně reprezentují, co daná proměnná představuje, respektive co přesně daná metoda dělá.
  • Udržujte metody co nejkratší. Počet řádků kódu by v ideálním případě neměl být víc než 50.
  • Vyvarujte se používání globálních metod a proměnných, pokud to není nutné. Sice jsou přístupnější, zato ale přispívají ke kolizi názvů, složitosti kódu nebo horšímu testování.

Příklad:

Budeme chtít získat jména všech uživatelů. Z toho logicky vyplývá, že budeme muset iterovat nad polem všech uživatelů a předat si získaná jména do nového pole. To bychom mohli udělat například tímto způsobem.

const names = [];
const people = [
	{ 
		name: 'Alice', 
		age: 22,
	},
	{
		name: 'Bob',
		age: 29,
	},
	// …
];

const getName = (item) => {
	return item.name;
}

const getNamesFromPeopleArray = (array) => {
	for (let i = 0; i < array.length; i += 1) {
		const item = array[i];
		names[i] = getName(item);
	}
}

getNamesFromPeopleArray(people);

Na první pohled se může zdát, že na kódu není co měnit. Vrací nám jména všech uživatelů, jak jsme si přáli. Náš kód jde ale napsat mnohem jednodušeji, a to pomocí funkce map().

const people = [
	{ 
		name: 'Alice', 
		age: 22,
	},
	{
		name: 'Bob',
		age: 29,
	},
	// …
];

const names = people.map(person => person.name);

2. DRY

Název: Don't Repeat Yourself (Neopakuj se).

Myšlenka: Nechť má každá část systému své jediné, jednoznačné a autoritativní zastoupení.

Popis:

Pokud jsme nuceni provádět změny v kódu, vykonáme je právě jednou namísto počtu duplicitních výskytů. DRY vyžaduje pouze jednu definitivní reprezentaci objektu, metody nebo proměnné, která tím představuje i jediný zdroj pravdy (tzv. Single Source of Truth), který je dalším z řady návrhových principů.

Díky tomu se vyvarujeme chybám v kódu, šetříme čas strávený údržbou a předcházíme duplicitám, které mohou přispívat ke zmatkům. Vývojáři se navíc nemusí neustále spoléhat na fulltextové vyhledávání.

Jak na to:

  • Předcházejte opakujícímu se kódu, například pomocí abstrakce, dobrým přehledem o projektu či pomocí code review.
  • Vyhněte se definování proměnných na více místech.
  • Omezte copy & paste vlastního kódu v aplikaci. Namísto toho jej přepište do logického a znovupoužitelného celku.

Příklad: Chceme definovat styly pro různé modifikace tlačítka. Každé tlačítko bude mít svou specifickou barvu pozadí i rámečku.

.button--red {
	border-color: darken(#ff0000, 10%);  
	background-color: #ff0000;
}

.button--green {
	border-color: darken(#00ff00, 10%);
	background-color: #00ff00;
}

Jednotlivé styly se od sebe liší pouze barvou. Redukovat opakující se kód můžeme například tímto způsobem, který je sice o něco upovídanější, zato přispěje ke granularitě kódu, abstrakci a snazšímu rozšíření.

$colors: (
	red: #ff0000,
	green: #00ff00
);

@mixin button-variants($color) {
	border-color: darken($color, 10%);
	background-color: map-get($colors, $color);
}

.button--red {
	@include button-variants(red);
}

.button--green {
	@include button-variants(green);
}

3. YAGNI

Název: You Aren't Going to Need It (Nebudeš to potřebovat).

Myšlenka: Neimplementujte funkcionalitu, dokud není potřeba.

Popis: „Kdybychom to v budoucnu potřebovali, bude to tam připravené.“ Typické programátorské „kdyby – chyby“, které může přispět k nabobtnání mrtvého kódu. Nepotřebný kód zanáší technický dluh do projektu, zvyšuje časové nároky a i jiné náklady s tím spjaté. V tomto případě platí motto:

„Co nemusíš udělat dnes, odlož na později.“

Jak na to:

  • Je-li některá funkcionalita opravdu třeba, využívejte výhod verzovacího systému, nebo práci doopravdy odkládejte na dobu, kdy bude třeba.
  • Prioritizujte svoji práci na základě aktuálních požadavků a implementujte jen to, co je v danou chvíli nutné.
  • Pokud provádíte refactoring kódu, zkontrolujte, že při přepisu odstraňujete všechny nepotřebné kusy kódu.

Příklad: Nebudete potřebovat 🙂.

4. Abstraction

Název: Abstrakce, též zobecnění.

Myšlenka: Jedno generalizované řešení je lepší než více specifických.

Popis:

Princip abstrakce přispívá ke znovupoužitelnému kódu, který se snáze rozšiřuje. Pokud se v kódu vyskytuje podobná funkcionalita, zvažme použití abstrakce. Obecné řešení umožňuje řešit více podobných podúloh prostřednictvím například jedné metody a do ní předaných parametrů. Abstraktní metody nám umožňují nesoustředit se na detaily v místech, kde to není třeba.

Typickým příkladem je dotazování se na položky v databázi. Zajímá nás přesné znění dotazu na databázi, pokud jen potřebujeme vypsat získané údaje na stránku? Nejčastěji ne. Bohatě se spokojíme s tzv. black boxem, ve kterém jsme odstíněni od konkrétní implementace a veškerých detailů a řešíme pouze návratovou hodnotu.

Jak na to:

  • Používejte parametrizované metody. Mějte ale na paměti, že všeho moc škodí. Pokud do metody předáváte více jak 5 parametrů, zvažte vhodnost svého řešení a zkuste kód rozdělit na ještě menší samostatné celky.
  • V případě stylů dávejte přednost @mixinům před @extend. Zlepší to přehlednost v kódu a sníží provázanost.
  • Pokud to daný jazyk umožňuje, pracujte s třídami, případně interfaces nebo abstraktními metodami.

Příklad:

Ukázkou budiž tento jednoduchý příklad @mixinu s media queries.

Napříč našimi styly potřebujeme definovat různé chování od daného breakpointu. Jedním z možných řešení může být následující.

// _button.scss

.button {
	padding: 10px;
	width: 100%;

	@media (min-width: 576px) {
		width: auto;
	}

	@media (min-width: 768px) {
		padding: 16px;
	}
}

Kvůli konzistenci a zamezení opakujícího se kódu by bylo vhodnější předat breakpointy do proměnných. S největší pravděpodobností nás při definování media queries ani nebudou zajímat přesné hodnoty těchto mezí, takže i ty můžeme odstínit od zbytku kódu.

Mnohem sofistikovanější by mohla být tato varianta.

// _breakpoints.scss

$breakpoint-values: (
	xs: 0,
	sm: 36em,  //  576 px
	md: 48em,  //  768 px
);

@mixin breakpoint-up($breakpoint) {
	@if (not map-has-key($breakpoint-values, $breakpoint)) or $breakpoint == 'xs' {
		@content;
	}

	@else {
		@media (min-width: map-get($breakpoint-values, $breakpoint)) {
			@content;
		}
	}
}

// _button.scss

.button {
	padding: 10px;
	width: 100%;

	@include breakpoint-up(sm) {
		width: auto;
	}

	@include breakpoint-up(md) {
		padding: 16px;
	}
}

Tímto řešením jsme dozajista ušetřili velké množství duplicitního kódu (DRY), učinili kód přímočařejším a jednodušším (KISS) a navíc jsme jej zobecnili. To nám přináší benefit v podobě škálovatelnosti mixinu, například na ověření retina obrazovky.

// _breakpoints.scss

@mixin breakpoint-up($breakpoint, $retina: false) {
	@if (not map-has-key($breakpoint-values, $breakpoint)) or $breakpoint == 'xs' {
		@if ($retina) {
			@media (min-resolution: 192dpi) {
				@content;
			}
		}
		// …
	}
	// …
}

5. SoC

Název: Separation of Concerns (Oddělení odpovědností).

Myšlenka: Udržování souvisejících komponent pospolu s minimální provázaností se zbytkem kódu.

Popis: Pojem odpovědnost můžeme v tomto kontextu chápat jako funkcionalitu. Vzpomínáte na špagety kód, ve kterém se vše prolínalo se vším a bylo těžké najít přehlednou strukturu v kódu? Oddělení odpovědností navrhuje strukturovat kód podle dílčích odpovědností, resp. funkcionalit.

Krásnou ukázkou mohou být například design patterns (návrhové vzory). Jedním z nejstarších je MVC (Model-View-Controller). Každá z vrstev představuje jakousi komponentu, která má jasně danou funkcionalitu, jež se liší od zbylých komponent. Díky tomu změna v jedné z komponent má minimální vliv na ostatní. Navíc jsme schopni docílit lepší přehlednosti v kódu, jeho znovupoužití, rozšíření a snazšího testování dílčí komponenty.

S tímto principem úzce souvisí principy low coupling (nízká provázanost) a high cohesion (vysoká soudržnost). Provázanost nám říká, jak moc je daná komponenta svázaná s ostatními. Soudržnost určuje, jak moc spolu funkcionality v dané komponentě souvisí.

Jak na to:

  • Zavádějte architekturu v kódu. Ať už se jedná o styly, databázovou vrstvu nebo celý projekt. Její přínos vám ušetří spoustu času i nervů. Vhodně sestavená architektura by se měla odrážet i v adresářové struktuře projektu.
  • Využívejte enkapsulace (zapouzdření) v podobě tříd či modulů. Každá metoda, která v ní bude, by neměla vykonávat více než jednu věc.

Příklad: Vyvíjíme prezentační firemní web, který obsahuje vysouvací mobilní menu, interaktivní kontaktní formulář a v zápatí mapu z Google Maps s adresou sídla firmy.

// index.js

const nav = document.querySelector('.js-nav');
const inputName = document.querySelector('.js-input-name');	
// …

// Metoda pro animaci navigace.
toggleNavigation();

// Validování dat z formuláře a následné zpracování dat.
validateForm();

// Vykreslení Google Mapy s vlastními ukazateli v mapě.
renderCustomMarksInGoogleMap(); 

Pro přehlednost nejsou jednotlivé metody implementovány. Kdyby byly, kolik řádků kódu tipujete, že by zabíraly? Určitě dost na to, abyste si řádně poscrollovali nebo v jednom kuse používali fulltextové vyhledávání 🙂.

// index.js

import './_contact-form.js';
import './_google-maps.js';
import './_nav.js';

// _nav.js
const nav = document.querySelector('.js-nav');
toggleNavigation();

// _contact-form.js
const inputName = document.querySelector('.js-input-name');
validateForm();

// _google-maps.js
renderCustomMarksInGoogleMap();

I na tomhle řešení by se dalo ještě leccos zlepšit, ale hlavní myšlenku principu se nám podařilo dodržet – rozdělit kód do komponent podle jejich funkcionality, což se i odrazilo ve struktuře souborů.

Závěrem

Existují i další principy, které mohou přispět ke zkvalitnění kódu a jsou stejně tak důležité jako ty výše zmíněné. Řeč je například o GRASP, SOLID, Dependency Injection, či o jednoduchých doporučení týkající se názvu proměnných, počtu řádků metody a mnoha dalších. Moc pěkné zpracování návrhových vzorů a principů můžete najít na Zdroják.cz.

Pouhé používání návrhových principů z kupky hnoje cihlu zlata neudělají. Představuje jeden z dílků skládačky, která zlepšuje kvalitu projektu. Pomáhá se zamýšlením se nad kódem samotným a přispívá tak k jeho čitelnosti a ještě lepšímu porozumění ze strany autora. Pokud se snažíme učinit kód více abstraktní, přímočařejší a jednodušší, v některých situacích musíme řešení přepsat více než jednou. Obrňte se proto trpělivostí a s vidinou lepšího kódu se jej snažte psát tak dobře, jak jen můžete.


Děkuji své druhé polovičce 👫 za zajímavé podněty a konzultace při psaní článku.


Související odkazy

  • Principy objektové orientovaného návrhu (Zdroják)
  • What Is Code Quality? And how to Improve Code Quality? (Perforce)
  • This KISS Principle in Software Development (Everything You Need to Know)

Úvodní obrázek byl inspirován přebalem knihy Spaghetti Code od Christopha C. Cempera.


Kateřina Klouček Dlouhá

Kateřina Klouček Dlouhá

Katka je kodérkou od roku 2017. V současné chvíli pracuje jako Design System Architect. Oplývá entuziasmem pro vše, co souvisí s UX nebo typografií. Více o autorovi

Další články od autora:

  • FrontKon 2024 obrazem
  • WebExpo 2024 je za rohem! + SLEVA NA VSTUPENKU
  • Proč (ne)dělat code review?
Více k tématu:
  • Kvalita kódu

Sdílejte

Líbí se vám článek? Podpořte jej sdílením!

X (Twitter) Facebook LinkedIn

Komentujte

Chcete k článku něco doplnit? Našli jste chybu? Napište e-mail.

Adam Kudrna

Nejnovější články

WebExpo — čtení na 3 min.

Pozvánka na WebExpo 2025

Rok se s rokem sešel, přichází měsíc květen a s ním WebExpo 2025, které se po nejistých letech usadilo v tomto jarním termínu. Jaké bude?

  • Adam Kudrna
    Adam Kudrna
Pozvánka na WebExpo 2025
JavaScript — čtení na 10 min.

Jak předcházet chaotické organizaci npm skriptů

Řešíte, jak organizovat skripty napříč projekty přehledně a konzistentně? Inspirujte se systémem, který zjednoduší práci vám i kolegům.

  • Tomáš Litera
    Tomáš Litera
Jak předcházet chaotické organizaci npm skriptů
Reportáž — čtení na 2 min.

FrontKon 2024 obrazem

Frontendisti letos připravili třetí ročník konference FrontKon. Ta se letos historicky poprvé odehrála naživo v Praze, a to v prostorách O2 Universum.

  • Kateřina Klouček Dlouhá
    Kateřina Klouček Dlouhá
FrontKon 2024 obrazem

Odběr novinek

Zadejte svůj e-mail a nenechte si ujít další nové články!

Odesláním formuláře souhlasíte se .
Zpracování osobních údajů probíhá za účelem zasílání newsletteru. Můžete se spolehnout, že vaše osobní údaje nebudeme s nikým sdílet. Z newsletteru se můžete kdykoli odhlásit. Stejně tak můžete kdykoli požádat o úplné smazání svých osobních údajů z naší databáze.
Zkontrolujte svoji e-mailovou schránku a potvrďte své přihlášení kliknutím na odkaz.

Všechna témata

  • Bootstrap
  • CSS
  • Design
  • Dokumentace
  • HTML
  • ITCSS
  • JavaScript
  • Kariéra
  • Kvalita kódu
  • Nástroje
  • No-code
  • Přístupnost
  • PWA
  • Reportáž
  • Rozhovor
  • Rychlost
  • Sass
  • Spolupráce
  • Typografie
  • Variable fonts
  • WebExpo
  • ✏️ Napište článek
  • Autoři
  • Cookies
  • Instagram
  • GitHub

Obsah na tomto webu je publikován pod licencí Creative Commons CC BY-NC 4.0.
Frontend Garden vysázel, zastřihuje a okopává (s ♥️) Adam Kudrna.
Založeno v květnu 2019.