Požadavek na modularizaci aplikace je přirozený a logický – zdánlivě nejde o nic víc než rozdělit aplikaci na více částí, které spolu příliš nesouvisí. Bohužel v praxi se něco takového realizuje, alespoň v prostředí Javy, docela obtížně. Musíme aplikaci dobře navrhnout a musíme používat netriviální technologie či postupy. Nejspíš narazíme již v prvním kroku – jak modularizovat datový model například v Hibernate? Řešení je vlastně docela snadné…
Co hledáme
Existují různé motivy modularizace. Může jít o potřebu vývojářů vhodně strukturovat a izolovat kód, může jít o snahu obchodníků vhodně customizovat produkt. Podle motivu a spousty dalších okolností pak zní odpověď na otázku, co to vlastně je modul… V tomto článku mám na mysli poměrně častý případ, kdy existuje jedno společné jádro aplikace a nad ním několik různých zakázkových úprav pro různé zákazníky. Na úrovni javového kódu pomůže dědičnost nebo návrhový vzor Strategie, ale datový model zůstává monolitický.
Co znamená modularizace aplikace konkrétně? Pro účely tohoto článku si můžeme představit situaci, kdy každý modul je umístěný v samostatném JARu.
Jak na to
Tato požadavky by se nejlíp řešily použitím databáze s méně striktním datovým modelem, než vyžaduje relační databáze, použili bychom tedy nějakou NoSQL databázi. Pro většinu současných komerčních aplikací by to bylo příliš odvážné řešení, pojďme hledat dál. Požadavky bychom mohli řešit programově – každý modul by o sobě věděl, co v datovém schematu potřebuje a uměl by datové schema upravit podle svých potřeb. To není špatné řešení, ale je pracné a náchylné k chybám. Neexistuje nějaké automatizovné řešení? Existuje…
Aspekty a Hibernate
Každý programátor používající Hibernate ví, že tento framework pro persistentci umí vytvořit automaticky datový model. Pokud například přidáme do naší persistentní třídy atribut a Hibernate je vhodně nakonfigurovaný, tak Hibernate do databázové tabulky sloupeček opravdu přidá. Tato vlastnost Hibernate se dá použít i pro naši modularizaci – potřebujeme ale nějak přesvědčit Javu, aby při přítomnosti modulu do persistentní třídy přidal atribut a při odstranění modulu atribut odebral. To se dá zařídit snadno – použitím aspektového programování.
Představme si nějakou entitu, například adresu, umístěnou v jádru aplikace.
@Entity public class Address { @Column(length=10) String street; @Column(length=20) String city; }
Adresu rozšíříme o atribut s PSČ, tento kód aspektu umístíme do rozšiřujícího modulu, který může, ale nemusí být součástí konkrétní instalace aplikace:
aspect Address_Module_Extension { @Column(length=6) String Address.zip; }
Limity
Výše uvedený princip je jednoduchý a názorný, ale je limitován rutinou Hibernatu, která má na starosti vytvoření a modifikaci datového modelu. Zatímco vytvoření datového modelu je záležitost fungující dobře, modifikace datového modelu není doporučeným postupem a v mnoha případech nefunguje. Přídání modulu do aplikace, která je již nainstalovaná a má tedy datový model již vytvořený, může způsobit problémy.
Tento způsob modularity jsme v jednom projektu opravdu využili, ale za velmi specifických podmínek. Nemohu nikomu doporučit modifikaci datového modelu pomocí Hibernate v produkčním nasazení. Berte tento článek jen jako zajímavost. Ale možná, že persistentní frameworky, které se snaží programátora odstínit od „starých a neflexibilních“ relačních databází, půjdou ve vývoji právě tímto směrem…
Napsat komentář