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

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).

Seriál: Principy objektově orientovaného návrhu (12 dílů)

  1. Návrhové principy: SOLID 9.5.2012
  2. Návrhové principy: Deméteřin zákon 18.5.2012
  3. Návrhové principy: DRY 30.5.2012
  4. GRASP – 1 – Úvod a Protected variations 20.6.2012
  5. GRASP – 2 – High cohesion 2.7.2012
  6. GRASP – 3 – Low coupling 16.7.2012
  7. GRASP – 4 – Polymorphism, Pure fabrication a Indirection 30.7.2012
  8. GRASP – 5 – Information expert a Creator 15.8.2012
  9. GRASP – 6 – Controller a jak GRASP používat 17.9.2012
  10. GRASP – 7– Modelové příklady 15.10.2012
  11. Návrhové principy: Tvorba balíčků (1/2) – Soudržnost 14.11.2012
  12. Návrhové principy: Tvorba balíčků (2/2) – Závislosti a provázanost 14.1.2013

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

Martin Jonáš pracuje jako projektový manažer v GrowJOB institute. Vystudoval Informační systémy na Fakultě informačních technologií VUT.

Komentáře: 2

Přehled komentářů

alblaho raději komponenty?
jablon PHP a composer
Zdroj: https://www.zdrojak.cz/?p=3739