Princípy SOLID pozostávajú z piatich usmernení pre čistý, udržiavateľný a flexibilný kód v objektovo orientovanom programovaní. Uplatňovanie a dodržiavanie týchto princípov vedie k ľahko zrozumiteľnému návrhu softvéru počas dlhých vývojových období. Vďaka týmto princípom je možné nielen písať lepší kód, ale aj ľahšie udržiavať existujúci kód.

Čo sú to SOLID princípy a kto ich vyvinul?

Dobrý zdrojový kód začína pravidlami, programovacími paradigmami a vhodným programovacím štýlom pre efektívny a čistý kód. Presne to zabezpečuje päť princípov SOLID, ktoré vymysleli Robert C. Martin, Bertrand Meyer a Barbara Liskov. Dodržiavaním týchto princípov v objektovo orientovanom programovaní (OOP) s jazykmi ako Python alebo Java nielenže píšete lepší kód, ale tiež zabezpečujete efektívnejšiu údržbu kódu, udržateľný a flexibilný dizajn softvéru a väčšiu bezpečnosť v dlhodobom horizonte.

Názov SOLID reprezentuje pevné programovacie základy, ktoré by mal mať každý, kto sa chce naučiť programovať. Samotná skratka bola vytvorená Michaelom Feathersom, ktorý na jej vytvorenie použil prvé písmená piatich princípov:

  • Princíp jedinej zodpovednosti: Trieda by mala mať jeden a len jeden dôvod na zmenu.
  • Princíp otvorenosti a uzavretosti: Softvérové entity (triedy, moduly, funkcie atď.) by mali byť otvorené pre rozšírenie, ale uzavreté pre modifikáciu.
  • Princíp Liskovovej substitúcie: Podtriedy by mali byť schopné zdediť a implementovať všetky metódy a vlastnosti nadradenej triedy.
  • Princíp oddelenia rozhraní: Rozhrania by nemali obsahovať viac metód, ako je potrebné na implementáciu tried.
  • Princíp inverzie závislosti: Triedy by nemali závisieť od iných tried, ale od rozhraní alebo abstraktných tried.

Aké výhody ponúkajú princípy SOLID?

Ak neexistujú žiadne pravidlá, nastáva chaos, čo je obzvlášť viditeľné pri programovaní. Aj malé chyby, nepresnosti a medzery môžu spôsobiť, že dobrý zdrojový kód bude z dlhodobého hľadiska úplne nepoužiteľný, ak sa „nevyriešia“. Niekedy stačia komplexné triedy, ktoré sťažujú implementáciu, alebo podtriedy, ktorým chýbajú individuálne vlastnosti ich nadradených tried. Princípy SOLID zabezpečujú, že čo najmenej kódu je potrebné opravovať refaktorizáciou.

SOLID princípy tvoria kód:

  • Prehľadné, čisté a atraktívne: Softvér a kódy sú ľahšie zrozumiteľné, efektívnejšie a jednoducho vyzerajú lepšie.
  • Ľahká údržba: Jednoduchá a prehľadná štruktúra uľahčuje viacerým spolupracovníkom údržbu a správu nových aj starších kódov.
  • Prispôsobiteľný, rozširovateľný, opakovane použiteľný: Vďaka zlepšenej čitateľnosti, zníženej zložitosti a zodpovednosti a zníženej závislosti na triedach je možné kód lepšie upravovať, prispôsobovať a rozširovať prostredníctvom rozhraní a flexibilne opakovane používať.
  • Menej náchylný na chyby: Čistý kód s jednoduchou štruktúrou znamená, že zmeny v jednej časti kódu nemajú náhodný vplyv na ostatné oblasti alebo funkcie.
  • Bezpečnejší a spoľahlivejší: Zníženie alebo odstránenie zraniteľností, nekompatibilít a chýb zvyšuje funkčnosť a spoľahlivosť systémov, čo zase zlepšuje bezpečnosť.

Čo znamenajú jednotlivé princípy SOLID?

Princípy SOLID patria medzi zlaté pravidlá dobrého programovania a mal by ich poznať každý, kto pracuje s objektovo orientovaným programovaním. Nižšie vysvetlíme každý princíp podrobne.

SRP: Princíp jedinej zodpovednosti

Robert C. Martin vytvoril pôvodnú definíciu tohto princípu v knihe „Agile Software Development: Principles, Patterns and Practices“ (Agilný vývoj softvéru: princípy, vzory a postupy), kde píše:

Citát

„Každý softvérový modul by mal mať jeden a jediný dôvod na zmenu“.

Princíp jedinej zodpovednosti (SRP) stanovuje, že každá trieda v objektovo orientovanom programovaní (OOP) by mala mať len jednu zodpovednosť. To znamená, že by mal existovať len jeden dôvod na úpravu triedy. Na rozdiel od bežných interpretácií to neznamená, že trieda alebo modul môže mať len jednu úlohu. Skôr to znamená, že by mala byť zodpovedná len za konkrétne úlohy, ktoré sa v ideálnom prípade neprekrývajú s inými oblasťami.

Prekrývanie zodpovedností, ako napríklad ponúkanie funkcií pre rôzne obchodné segmenty, môže ovplyvniť funkčnosť triedy, ak sa vykonajú úpravy v jednom segmente. Vykonávanie viacerých zodpovedností a existenciu mnohých závislostí môže spôsobiť, že jediná zmena v jednej oblasti spôsobí chyby v kóde alebo potrebu ďalších zmien.

Princíp jedinej zodpovednosti (SRP) je navrhnutý tak, aby vytváral ucelené moduly s konkrétnymi, jasne definovanými funkciami alebo objektmi. Vďaka jasnej, štruktúrovanej konfigurácii s minimálnymi závislosťami a nezávislými implementáciami je možné vykonávať úpravy a zmeny efektívnejšie, rýchlejšie a plynulejšie.

Poznámka

Triedy, tiež známe ako typy objektov, sú ústrednými prvkami objektovo orientovaného programovania (OOP). Možno ich považovať za vzory objektov, ktoré opisujú ich atribúty, aby bolo možné v softvéri vytvoriť objekty a koncepty reálneho sveta. Triedy, tiež známe ako moduly, sa často porovnávajú s typmi súborov.

OCP: Princíp otvorenosti a uzavretosti

Podľa Roberta C. Martina a Bertranda Meyera v knihe „Object Oriented Software Construction“ (Objektovo orientovaná konštrukcia softvéru) OCP stanovuje:

Citát

„Softvérové entity (triedy, moduly, funkcie atď.) by mali byť otvorené pre rozšírenie, ale uzavreté pre úpravy“.

OCP zaručuje, že na implementáciu zmien nemusíte prepísať jadro softvéru. Ak sú potrebné hlboké úpravy kódu, existuje riziko vzniku jemných chýb a kódových chýb. Dobře strukturovaný kód by mal poskytovať rozhrania, ktoré možno použiť na jeho rozšírenie o ďalšie funkcie. Kľúčovým slovom je tu dedičnosť tried.

Nové vlastnosti a rozšírenia s jasnými novými funkciami a metódami, ktoré je potrebné implementovať, možno ľahko pridať do nadradenej triedy prostredníctvom rozhrania vo forme podtried. Takto nemusíte zasahovať do napísaného, stabilného kódu. Zjednodušuje to údržbu a starostlivosť o softvér a výrazne zlepšuje efektívnosť opätovného použitia stabilných prvkov kódu prostredníctvom rozhraní.

LSP: Liskovov princíp nahraditeľnosti

Podľa Barbary H. Liskovovej a Jeannette M. Wingovej v článku „Behavioral Subtyping Using Invariants and Constraints“ (Behaviorálne podtypy s využitím invariantov a obmedzení) LSP uvádza, že:

Citát

„Nech q(x) je vlastnosť, ktorú možno dokázať o objektoch x typu T. Potom q(y) by malo byť možné dokázať pre objekty y typu S, kde S je podtyp T“.

Možno to znie tajomne, ale v skutočnosti je to celkom jednoduché na pochopenie: prepojené alebo rozšírené podtriedy musia fungovať ako ich nadradené triedy alebo základné triedy. To znamená, že každá podtrieda musí zachovať vlastnosti svojej nadradenej triedy prostredníctvom dedičnosti a tieto vlastnosti sa nesmú v podtriedach meniť. V zásade musia byť nahraditeľné, odtiaľ pochádza princíp nahraditeľnosti. Nadradené triedy, naopak, môžu byť modifikované.

Na vysvetlenie si pozrime klasický príklad Roberta C. Martina o obdĺžnikoch a štvorcoch. V hodinách geometrie sa učíme nasledujúci princíp: každý štvorec je obdĺžnik, ale nie každý obdĺžnik je štvorec. Štvorec má nielen pravouhlé strany ako obdĺžnik, ale všetky jeho strany sú aj rovnako dlhé.

V programovaní predpoklad, že podobné alebo zdanlivo identické triedy sú navzájom prepojené alebo závislé, vedie k chybám, nedorozumeniam a nejasnému kódu. Z tohto dôvodu v programovaní trieda „Rectangle“ nie je štvorec a trieda „Square“ nie je obdĺžnik. Obe sú oddelené a implementované samostatne. Bez integrovaného prepojenia medzi triedami nemôžu nedorozumenia viesť k chybám medzi triedami. To zvyšuje bezpečnosť a stabilitu pri výmene implementácií v podtriedach alebo nadradených triedach bez negatívnych dôsledkov.

ISP: Princíp oddelenia rozhraní

Podľa Roberta C. Martina v knihe „The Interface Segregation Principle“ je ISP definovaný takto:

Citát

„Klienti by nemali byť nútení závisieť od rozhraní, ktoré nepoužívajú“.

ISP uvádza, že používatelia by nemali byť nútení používať rozhrania, ktoré nepotrebujú. Inými slovami: aby bolo možné klientom poskytovať funkcie určitých tried, nové, menšie rozhrania sú prispôsobené špecifickým požiadavkám. Tým sa zabráni tomu, aby rozhrania boli príliš veľké, a zabezpečí sa, že medzi triedami nevzniknú silné závislosti. Výhodou je, že softvér s oddelenými triedami a niekoľkými malými rozhraniami prispôsobenými špecifickým požiadavkám sa ľahšie udržiava.

DIP: Princíp invertovania závislostí

Podľa Roberta C. Martina v „Princípe závislosti“, piatom a poslednom zo SOLID princípov, je to nasledovné:

Citát

„A. Moduly vysokej úrovne by nemali závisieť od modulov nízkej úrovne. Oba by mali závisieť od abstrakcií. B. Abstrakcie by nemali závisieť od detailov.“

DIP zabezpečuje, že špecifické funkcie a závislosti v rámci vrstiev zdrojového kódu sa spoliehajú na abstraktné rozhrania, nie priamo na seba navzájom. Softvérové architektúry sú zvyčajne organizované do vyšších užívateľských úrovní a nižších, abstraktnejších úrovní. Logicky by sa dalo predpokladať, že abstraktný základ ovplyvňuje správanie vyšších vrstiev. DIP však identifikuje potenciálny problém, keďže vytvára závislosti vyšších úrovní na nižších úrovniach, čo môže viesť k problémom.

Namiesto prepojenia vyšších úrovní s nižšími úrovňami by triedy na vysokých a nízkych úrovniach mali závisieť od abstraktných, stredných rozhraní. Rozhrania získavajú funkcie, ktoré sú potrebné na vyšších úrovniach, z nižších úrovní a sprístupňujú ich. Týmto spôsobom je možné vyhnúť sa hierarchii závislostí zdola nahor, ktorá môže v priebehu času viesť k chybám v kóde. To uľahčuje opätovné použitie modulov a umožňuje zmeny v nižších triedach bez ovplyvnenia vyšších úrovní.

Čo sa stane, ak nebudú dodržané zásady SOLID?

Vytváranie čistého, čitateľného kódu, ktorý zjednodušuje údržbu, by malo byť primárnym cieľom vývoja softvéru. Ak vývojári prehliadnu základné usmernenia, ako sú princípy SOLID, kód sa môže výrazne zhoršiť v dôsledku zraniteľností, nadbytočností, nahromadených chýb a nadmerných závislostí. V extrémnych prípadoch sa kód môže s časom stať nepoužiteľným. Ide o významný problém v agilnom vývoji softvéru, kde mnoho ľudí často pracuje na zložitých úlohách kódovania.

Medzi dôsledky nečistého kódu alebo zlej údržby kódu patria:

  • Zápach kódu: Ak kód nie je napísaný v súlade s potrebnými štandardmi, môže to spôsobiť zápach kódu alebo „smradľavý kód“, čo vedie k funkčným chybám a nekompatibilným programom.
  • Zhoršenie kódu: Ak nie je kód udržiavaný alebo opravovaný refaktorizáciou alebo nákladnou revíziou kódu, môže obrazne „zhnitiť“ a úplne stratiť svoju funkčnosť. Iný termín pre nečitateľný, spletitý kód je spaghetti kód.
  • Bezpečnostné riziká: Problémy, ktoré vznikajú, sa neobmedzujú len na výpadky, zložitú údržbu a problémy s kompatibilitou. Existujú aj bezpečnostné medzery, ktoré poskytujú malvéru príležitosti na zneužitie kódu, vrátane zero-day exploitov.

Kto vyvinul princípy SOLID?

Pôvod princípov SOLID spočíva v niekoľkých princípoch, ktoré ako prvý predstavil Robert C. Martin („Uncle Bob“), jeden z iniciátorov agilného programovania, v roku 2000 vo svojej eseji s názvom „Design Principles and Design Patterns“ (Princípy a vzory dizajnu). Princípy SOLID vymysleli Robert C. Martin, Bertrand Meyer a Barbara Liskov. Chytľavú skratku popularizoval Michael Feathers, ktorý preusporiadal počiatočné písmená piatich základných princípov do zapamätateľného poradia.

Aké podobné programovacie princípy existujú?

V oblasti vývoja softvéru sú princípy všeobecnými alebo veľmi špecifickými usmerneniami a odporúčaniami pre konanie. Okrem princípov SOLID, ktoré boli vyvinuté pre objektovo orientované programovanie, medzi ďalšie programovacie princípy pre čistý kód patria:

  • Princíp DRY (Don’t repeat yourself – Neopakuj sa) pre funkcie s jedným jedinečným vyjadrením
  • Princíp KISS (Keep it simple, stupid – nechaj to jednoduché, hlupák) pre kód zostavený čo najjednoduchšie
Prejsť na hlavné menu