How To Deal With J2EE and Design Patterns

Patterns are clearly defined as:

"In software engineering, a design pattern is a general reusable solution to a commonly occurring problem within a given context in software design."
[http://en.wikipedia.org/wiki/Software_design_pattern].

If you encounter a design challenge, you are supposed to search in a catalog for the description, compare the Motivation (Forces) or Applicability. If they match, you can apply the ideas from the pattern to solve your problem. Patterns are not a genius solution to a problem, rather than a standardized compromise. Usually you are going to implement flavors of the design patterns without even knowing it.

In Java Enterprise community patterns seem to have their own live. They are going to be applied regardless their problem definition or context. The most misused pattern in the Java Enterprise community is the DTO. DTO was clearly defined as a solution for a distribution problem. DTO was meant to be a coarse-grained data container which efficiently transports data between processes (tiers). In J2EE DTO was absolutely necessary, CMP Entity Beans were not serializable. Martin Fowler also defines defines DTO as:

"An object that carries data between processes in order to reduce the number of method calls."
According to the definitions DTOs were never meant to carry data within a JVM...

Even more suspicious is the popularity of the DAO pattern. The solution statement starts as:

"The DAO implements the access mechanism required to work with the data source. The data source could be a persistent store like an RDBMS, an external service like a B2B exchange, a repository like an LDAP database, or a business service accessed via CORBA Internet Inter-ORB Protocol (IIOP) or low-level sockets."

DAO was always meant as a procedural encapsulation of inconvenient or not standardized data sources. An object oriented flavor, the Domain Store pattern uses DAO to access JDBC and provides an object oriented access to the store. Interestingly the Domain Store looks like a slightly modified version of the ...JPA Entity Manager.

Some projects are wrapping Entity Manager with an empty delegate and call it "DAO". Such an approach is actually the opposite of the origin intention...

Java EE 5 killed the majority of the J2EE Patterns. Their "Problem" and "Forces" descriptions do not apply any more. Java EE 6 and 7 killed the remaining patterns, only the Application Service is still useful.

If you take the pattern definitions seriously and look at some "enterprise" projects you are not going to understand the design. Patterns are going to be applied without having a problem and are considered as future "insurance": "...in case JPA disappears, I only have to change the implementation of the DAO..."

How to deal with patterns? Apply them if you encounter a problem. Java EE design is "bottom-up" rather than "top-down", as it was the case in the old J2EE world.

[See also an in-depth discussion in the "Real World Java EE Night Hacks--Dissecting the Business Tier" book, page 259 in, chapter "Data Access Object"]

We spend some time to eliminate J2EE and GoF patterns one by one with Java EE 7 and Java 8 during the Java EE Architectures "airhacks" workshops at MUC airport.


NEW online workshop: WebStandards Igniter (online)

Airport MUC workshops: Java EE 7: Bootstrap, Effective, Architectures, Web, React and Angular, Testing and Microservices

Podcast: airhacks.fm and newsletter: airhacks.news

A book about rethinking Java EE Patterns

Comments:

Hi Adam,

There is one reason to still use DAOs: if you want to mock the data access in unit tests.
Because mocking the EntityManager is not easy (i.e. Queries)

Kind regards,
Simon

Posted by Simon Martinelli on August 21, 2014 at 11:16 AM CEST #

Hi Simon,

with about three lines of code you can mock the EntityManager with Queries. Usually I do it once and reuse the code in Unit Tests,

see you soon,

cheers,

adam

Posted by Adam Bien on August 21, 2014 at 11:21 AM CEST #

Can you provide the code?
How do you create the result list?

Posted by Simon Martinelli on August 21, 2014 at 12:34 PM CEST #

I wrong if I say that many patterns are now encapsulated on standard frameworks? For example, BussinessDelegate, Controller, and others view frameworks are now encapsulated on JSF. ServicesLocator with DI (and CDI with stereotypes) ?

Other situation where for me DTO are necesary is for interoperability between systems with differents domain, but that still shares some concerns.

But also, and now a days with JavaEE7 and @Transactional interceptor on CDI, "multilayered applications" may consist of one layer of bean (CDI) and EntityClasses so many patterns are not neccesary used.

Posted by martdominguez on August 21, 2014 at 12:50 PM CEST #

Hi Adam,

Let's see the following situations.

Situation A:
You are using JPQL embedded right into the java code, like this:

List<Customer> list = em.createQuery(
"SELECT c FROM Customer c WHERE c.name LIKE :custName")
.setParameter("custName", name)
.setMaxResults(10)
.getResultList();
for (Customer customer: list) {
//do something with the customer
}

The point here is that way how we obtain the customer list, and how we process isn't separated. This can be a maintenance nightmare. I rather use something like this:

List<Customer> list = someObject.findCustomerByName(name, 10);

for (Customer customer: list) {
//do something with the customer
}

The question is that how would you call the someObject in this example?

Situation B:
You are using name queries, like this:
@Entity
@NamedQuery(name="findCustomerByName", query="SELECT c FROM Customer c WHERE c.name LIKE :custName")
public class Customer {
}

List<Customer> list = = em.createNamedQuery("findCustomerByName", Customer.class).setParameter("custName", name)
.setMaxResults(10)
.getResultList();

for (Customer customer: list) {
//do something with the customer
}

Here, I still believe it worth to move the query code into a different, just we did in situation A.

Situation C:
Just like situation A, but with criteria builder. The resuls also the same.

So, my conclusion is that it worth to move the query code into a different class, which can hide the details of the query, because this helps to keep the code clean, and separate the responsibilities. Most of the developers call these kind of classes to DAO. I'm pretty sure, that you also write classes with the same role.

Posted by Peter Boszormenyi on August 21, 2014 at 01:38 PM CEST #

Hi Peter,

you can encapsulate complex queries in a dedicated class (a control from BCE / ECB). However, such a class is not the realization DAO pattern.

...it is just a class which encapsulates a query. A product of "divide and conquer".

My point is: do not redefine common patterns for your needs -- it becomes confusing and counter-productive.

I also encapsulate complex and reusable queries in a dedicated class, but do not call it a DAO :-).

cheers,

adam

Posted by Adam Bien on August 21, 2014 at 07:55 PM CEST #

@Peter

I believe this would be a repository, which is close to a DAO but not quite the same (it usually has a higher level of abstraction and a closer relation to business problems).

Posted by Max Fichtelmann on August 22, 2014 at 10:02 AM CEST #

Hi Adam,

Isn't DAO also meant to abstract all the handling with the DB?

For example:
I have an interface LoginDAO with CRUD methods. Now i can implement it and create a wrapper class for each data source (e.g. RDBMS using JPA, RDBMS with JDBC, NoSQL driver API and etc... ).
Then I just need to change the reference of LoginDAO in my code when i want to change the data source that store the login info.

Posted by Eyal on August 22, 2014 at 10:35 AM CEST #

@Eyal,

do you really have to access JPA, JDBC, NoSQL from one application at the same time?

If yes, DAO would be the right solution.

cheers,

adam

Posted by Adam Bien on August 22, 2014 at 10:44 AM CEST #

Hi Adam,

I frequently use data only POJOs:
- to hide to the application upper levels the table/entity structure information belonging to the data layer
- to map to a single POJO data from different entities
- because a simple POJO can be serialized and converted to xml and JSON in an easier way than some complex entities

I name these objects DTOs.

Am I wrong ?

Posted by Gualtiero on November 13, 2014 at 09:26 PM CET #

Post a Comment:
  • HTML Syntax: NOT allowed
realworldpatterns.com
Online Workshops
...the last 150 posts
...the last 10 comments
License