Přejít k navigační liště

Zdroják » Různé » Návrhové principy: Tvorba balíčků (1/2) – Soudržnost

Návrhové principy: Tvorba balíčků (1/2) – Soudržnost

Články Různé

V tomto díle seriálu se podíváme na tři principy používané pro udržení vysoké soudržnosti při seskupování tříd do balíčků (packages).

Nálepky:

V tomto díle se podíváme na první část principů pro návrh objektově orientovaných systémů na makro úrovni. Zabývat se budeme návrhem struktury systému na vyšší úrovni, než jsou jednotlivé třídy – na úrovní balíčků.

Balíček – pod pojmem balíček budeme v tomto článku rozumět balíček tak, jak je obvykle chápán v prostředí jazyka Java. Tedy jako modul tvořený seskupením tříd, které je možné společně začlenit (importovat) do našeho kódu.

Tvorba balíčků přináší řadu otázek, kterými se musíme zabývat. Principy probírané ve článku přinášejí základní odpovědi na ty nejdůležitější z nich. V prvním díle se zaměříme na principy týkající se vysoké soudržnosti  (cohesion) balíčků. Druhý díl se bude zabývat jejich provázaností  (coupling).

Uvedené principy vycházejí především z článků, které napsal Robert „Uncle Bob“ C. Martin.

1 Reuse/release Equivalence Principle – REP

The unit of reuse is the unit of release. Effective reuse requires tracking of releases from a change control system. The package is the effective unit of reuse and release.

Vydávejte znovupoužitelné jednotky

Znovu-použití kódu by nikdy nemělo probíhat jeho zkopírováním do jiného projektu. Pokud kód zkopírujeme, odřízneme se od možnosti snadno získat jeho novější verze obsahující opravy chyb nebo nové funkce. Zodpovědnost za údržbu zkopírovaného kódu přechází na nás.

Kód by měl být znovu používán pouhým zahrnutím určitého vydání knihovny do našeho kódu. Měli bychom ho používat jako nezávislý produkt. Nemělo by vůbec být potřeba mít ke zdrojovému kódu přístup.  Z pohledu uživatele bychom balíček měli vidět pouze jako black-box, do kterého nelze zasahovat. Za jeho údržbu by měl být zodpovědný původní autor.

Efektivní znovupoužití vyžaduje možnost sledovat vydání nových verzí.

Autor knihovny musí jednotlivé vydané verze jednoznačně identifikovat pomocí názvů nebo čísel verzí, aby její uživatelé mohli od sebe jednotlivé verze odlišit. Uživatelé musí být vhodným způsobem informováni o nových verzích a změnách, které zahrnují.

Balíčky jsou efektivní jednotkou pro vydání a znovupoužití.

Většina tříd v typické aplikaci/knihovně vyžaduje několik spolupracujících tříd ke své funkci. Znovu použít konkrétní třídu samostatně je tak obtížné.  Obvyklý softwarem také obsahuje příliš mnoho tříd na to, aby bylo možné každou z nich vydávat samostatně. Mnohem efektivnější (pro autora i uživatele) je tedy vydávat více souvisejících tříd v podobě balíčku, který poskytuje nějakou ucelenou funkčnost.  Pokud jsou třídy seskupeny do balíčků je mnohem jednoduší udržovat přehled o jejich závislostech – počet závislostí mezi balíčky je řádově nižší než počet závislostí mezi třídami.

2 Common reuse principle – CRP

The classes in package are reused together. If you reuse one of the classes in package, you reuse them all.

Třídy v balíčku jsou vždy používány společně

Tento princip nám dává základní vodítko k určení, které třídy patří do stejného balíčku. Balíčky jsou znovu používány, jako celek. Proto by balíček měl obsahovat třídy, které jsou obvykle znovu používány společně. Pokud tedy máme skupinu úzce spolupracujících tříd, měly by být umístěny do jednoho balíčku. Balíčky by měly z pohledu jejich uživatele poskytovat množinu souvisejících funkcí z určité oblasti. A všechny třídy související s touto oblastí funkčnosti by měly být v jednom balíčku.

Pokud používáte jednu třídu balíčku, používáte celý balíček

Uživatel balíčku by měl typicky využívat většinu tříd z balíčku.  Neměli bychom vytvářet balíčky obsahující skupinu tříd, z nich typický uživatel použije pouze malou část.  Každé nové vydání balíčku by pak nutilo k přechodu na novou verzi i uživatele, kteří používají pouze třídy, které se nezměnily. (Nebo by museli u každé nové verze ověřovat, zda se jich změny týkají nebo ne, což by bylo nejspíše ještě pracnější.)

Důsledkem tohoto principu je tlak na vydávání většího množství menších balíčků. To může být v rozporu s principem REP. Vydání většího množství menších balíčků zvyšuje množství závislostí balíčků, které musí jejich uživatel hlídat. Vždy je nutno vyvážit tyto protichůdné síly (malé balíčky se složitější kontrolu závislostí vs. velké balíčky, které je třeba častěji aktualizovat).

3 Common Closure Principle – CCP

The classes in a package should be closed together against same kinds of changes. A change that affects a package affects all the classes in that package.

Každá změna by měla ovlivnit co nejmenší možný počet balíčků

Třídy, které se mění z podobných příčin, by měly být rozděleny do co nejmenšího počtu balíčků.  Pokud se pak vyskytne potřeba změny, zasáhne v ideálním případě pouze jeden balíček. To nám umožňuje minimalizovat množství práce související s vydáním nových verzí balíčků, protože není nutné tak často vydávat nové verze všech balíčků.

Tento princip úzce souvisí s Open-closed principle.  Třídy není nikdy možné zcela uzavřít vůči nutnosti provádět jejich změny. Vždy je však navrhujeme tak, aby byly uzavřeny (nebylo nutné je měnit) vůči nejpravděpodobnějšímu typu změn (viz Protected variations). Princip CCP nám říká, že bychom do jednoho balíčku měli seskupit všechny třídy, které nejsou uzavřeny uzavřít vůči stejnému typu změn.

Závěr

Tyto principy představují tři vrcholy trojúhelníka znázorňujícího výhody a nevýhody představované jednotlivými principy.

Při rozdělování tříd do balíčků a jejich uvolňování pro znovu-použití bychom měli naše rozhodnutí vždy zvážit z pohledu těchto tří principů a zvolit vhodný kompromis, který vyváží výhody a nevýhody různých řešení.

Pokračování příště

V příštím díle se podíváme na tři principy, kterými bychom se měli řídit při zvažování závislostí mezi balíčky.

Zdroje a další informace

Komentáře

Subscribe
Upozornit na
guest
2 Komentářů
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
View all comments
alblaho

Mám obavu, že balíčky jak je známe z Javy, nejsou vhodnou entitou k samostatnému nasazení a verzování. Jsou tak nějak na půl cesty a řeší to až sofwarové komponenty, jako třeba OSGi.

Ale zase, OSGi docela nesnáším, je to docela komplikované, výpisy zásobníků jsou gigantické, OSGi aplikace bývají často svázány s Eclipse.

jablon

Pracuji v PHP. Z praxe vím, že vytvářet velké composer balíčky znamenalo častou údržbu a vydávání nových verzí. Menší balíčky se napsali jednou a změna přišla třeba za půl rok. Závyslosti se pak dali lehce vyčíst … ono když se balíček dobře navrhne, tak změny jsou v podstatě jen v opravách chyb připadně rozšíření API. Osobně bych se velkým balíčkům vyhnul a rozsekal to na malé, které řeší jenom jeden konkrétní prblém. Ve velkém balíčku pak ještě vzniká problém, že ne vše se využívá…

Enum a statická analýza kódu

Mám jednu univerzální radu pro začínající programátorty. V učení sice neexistují rychlé zkratky, ovšem tuhle radu můžete snadno začít používat a zrychlit tak tempo učení. Tou tajemnou ingrediencí je statická analýza kódu. Ukážeme si to na příkladu enum.

Pocta C64

Za prvopočátek své programátorské kariéry vděčím počítači Commodore 64. Tehdy jsem genialitu návrhu nemohl docenit. Dnes dokážu lehce nahlédnout pod pokličku. Chtěl bych se o to s vámi podělit a vzdát mu hold.