Domain Model: Del disseny a la implementació persistent

A l’article Domain Model: De l’anàlisi al disseny hem parlat del patró de disseny Domain Model i de com arribar a un conjunt de classes software a partir d’un model conceptual d’anàlisi. El que ens proposem en aquest article és donar el següent pas cap a la implementació i tractar la problemàtica de com fer persistents les dades que conté aquest model. La solució proposada es basarà en la tecnologia JPA (Java Persistence API) que ens permet lligar aquest model del domini amb l’estructura de la base de dades relacional.

JPA defineix una família d’implementacions del patró Data Mapper que defineix en Martin Fowler, al seu llibre Patterns of Enterprise Application Architecture. Aquesta tecnologia assumeix que hi ha una base de dades relacional que té una certa similitud amb el model del domini ja que totes dues haurien de ser derivats d’un mateix model: El model conceptual del domini.

El nostre subsistema JPA (a l’article farem servir Hibernate com a referència) requereix que se li subministrin dades addicionals sobre com s’ha d’establir la correspondència entre el model del domini i el model físic de la base de dades.

El principi d'inversió de dependències ens diu que hem d’implementar aquest model del domini sense dependre de detalls específics de la plataforma, per la qual cosa hauriem de subministrar aquestes metadades de manera independent del codi de les classes del model del domini (de fet, aquest és l’enfocament inicial de moltes eines de mapeig objecte-relacional i encara es pot fer servir amb JPA).

A la pràctica, però, s’ha demostrat que el fet d’haver de mantenir dos fitxers diferents per a cada entitat, un fitxer java amb la classe que la implementa i un fitxer (típicament xml) de mapeig amb les dades de persistència i mantenir-los sincronitzats és també costós i propens a errors, per la qual cosa necessitem un enfocament mixte. Una de les grans novetats de JPA ha sigut, precissament, aportar aquest enfocament mixte gràcies a l’ús d’anotacions (novetat de Java 5). Aquesta solució, com qualsevol solució basada en anotacions, implica un cert acoblament del codi java cap les anotacions de JPA (és necessari JPA per compilar el codi) però permet l’execució del codi anotat en un entorn no-JPA.

Finalment, necessitem un punt d’entrada al subsistema JPA que permeti a les classes de la capa de domini recuperar instàncies d’objectes de la base de dades o actualitzar la base de dades amb les dades que tenim al model del domini. JPA ens ofereix la interfície EntityManager que ens dóna accés a aquest subsistema amb una interfície prou simplificada per executar consultes, recuperar instàncies a partir del seu identificador o actualitzar instàncies.

Una opció que ens podem plantejar, doncs, és fer servir l’EntityManager des de les classes de la capa de domini; el principal problema d’aquesta opció és que, si apliquem el principi d'inversió de dependències , les classes de la capa de domini no haurien de dependre de l’EntityManager ja que aquest és menys abstracte i, per tant, hem d’introduir una abstracció intermitja: El controlador de dades o diccionari de dades. Aquesta interfície definirà les operacions que la capa de domini necessita de la capa de dades i la seva implementació farà d’adaptador entre aquesta interfície i la interfície oferta per l’EntityManager. A continuació es mostra un diagrama UML amb els elements que formarien part d’aquesta solució:

Conclusions

S’ha proposat una solució que permet sincronitzar el model del domini amb el model persistent de les dades amb un cost de codificació mínim ja que només s’han de codificar les metadades de mapeig, les consultes que es considerin necessàries i els adaptadors de dades. A més, la solució proposada permet mantenir un compromís òptim entre independència entre el model del domini i el subsistema de persistència i facilitat de manteniment mitjançant l’ús d’anotacions.

No s’ha considerat a l’article com definir aquestes metadades de mapeig (es poden trobar a l’article Implementació de models conceptuals persistents amb Java i JPA ).

blog comments powered by Disqus