Adam Bien's Weblog

Thursday Mar 11, 2010

Modules, Cycles, Unwanted Friends - The Modularity Challenges In Enterprise Projects

Building modules and components is not that hard. You "only" have to encapsulate the internal component implementation and expose a clean and easy to use interface. ...at least on paper. In practice you will be confronted with the following challenges in the early iterations:

  1. The external interface is too coarse and far less interesting for internal reuse, than you had thought.
  2. The interesting things are residing inside the component. They are, however, well encapsulated and not accessible from the outside.

Example: you have two independent components; customermgmt and address / geo-location service. The module customermgmt exposes CRUD services and the address component extensive search capabilities. So far the world is perfect.
Now: a customer has an address - how to model that? The external, customer contract will have to reference the address somehow. That is often modeled as a direct relation between DTOs (just a getter). The external view of the customer component is now dependent on the address component. The implementation is still independent.

The relation between the customer and the address has to be persisted somehow. And now the trouble starts. Now the implementation of the customer component is dependent on the address component - because of direct (JPA) link between both modules. Now the internal implementation *and* the component contract are dependent on each other.

You are using JPA 1.0 - and your database experts just don't want to introduce an additional mapping table between the customer and the address. So you have to model a bi-directional relation between the customer entity and the address (introducing a back-link with a mappedBy attribute). Now you get a bidirectional dependency between the implementation of your component - the external dependency of the customer can remain unidirectionally dependent on the address. This is only true if you are using DTOs.

So you get two components which should be independent of each others, but are actually tightly coupled. Your modules have to expose everything - if you are using Java EE 6 - the DTOs and JPA-entities are dependent of each other - probably only the very thin boundary may remain independent. In practice you will get e.g. an invoice module in addition, which will be dependent on both the customer and the address....

You can do the following to "improve" the situation:
  1. Factor out all entities into a common package. Often called "domain", "model" or even "common". Such a common package is not cohesive (it contains multiple business concepts) and also not very good to maintain (the generic names have nothing to do with the actual business). This approach looks great ...on paper.
  2. Drop JPA-relations and introduce proxy-objects, which contain the ID and can be resolved on demand. This will significantly increase the amount of code and will hit your performance. You will be not able to use joins...
  3. Allow bidirectional friend-dependencies between modules. In that case it will be hard to introduce a framework like OSGi, jigsaw or something else. But you can still put all "business components" into few modules. Then the real benefit of OSGi, Jigsaw etc is questionable.
  4. Remove OR-mappers and go with "plain" JDBC. Let the DB handle the dependencies for you. In most cases this is not really a maintainable option.
Dependencies between persistent objects from different modules are practically not existing in other domains like IDEs, servers or plugins, but are the standard case in enterprise projects.
So, you shouldn't kill any OSGi project - you should implement some typical use cases (PoCs) with modularity solution of your choice before the project really starts. This is actually independent of any framework like OSGi, jigsaw or EMS (esoteric module system) :-).

[See also "Real World Java EE Patterns, Rethinking Best Practices" book, Page 267, (Monolithic or Loosely Coupled?) for more in-depth discussion]


[my tweets]  Rss My book: Real World Java EE - Rethinking Best Practices

Kommentare:

In a project I'm working on we had a problem with some domain entities depending on User object (which resided in a separate module, exposing just a DTO). The solution we came to was to map the UserDTO to the same database table as User entity and use this DTO in entity classes in other components, defining relationship as if it were a regular entity (we don't allow cascading saves/updates to the UserDTO fields).

The drawback is that we can't let JPA generate the DB schema, as DTO are read-only and have insertable="false" on it's columns (not a big pain for us though, as we have other DTOs mapped to database views anyway, aggregating data from different domain entities in one transfer object).

Works great for now, we'll see what happens when the project grows bigger.

Gesendet von Marcin Deryło am March 11, 2010 at 02:24 PM CET #

@Marcin,

exactly - in another project we used materialized views for similar purposes. Typical business "enterprise" projects are lot harder to partition, than the technical stuff. ...and no framework can help us here :-),

thanks for your thoughts!,

adam

Gesendet von Adam Bien am March 11, 2010 at 02:39 PM CET #

Why would you separate customer from his address?

What would you do with independent address component?

I think customermgmt component should contain customer's address similiary as it contains customer's name, age, etc.

Gesendet von Wojciech Gdela am March 12, 2010 at 03:02 PM CET #

@Wojciech,

it is just an example. You get the same problem with orders, invoices and e.g. statistics.

If you are not careful, you will end with a huge package with too many, not-cohesive entities...

thanks!,

adam

Gesendet von Adam Bien am March 12, 2010 at 06:47 PM CET #

We encapsulate a function and separate from external interface. We can access the address by using accessor and mutator provided by function. Isn't it?

Gesendet von Free Virus Removal am July 18, 2010 at 06:24 AM CEST #

Senden Sie einen Kommentar:
  • HTML Syntax: Ausgeschaltet
Meta-stuff / Interviews
My Recent Book
Java One 2009
CommunityOne East N.Y.C
JavaONE 2008 Interview
Search
...the last 150 posts
...the last 10 comments
greenfire.dev.java.net
Links
my.netbeans.org
Visitors
License