I've been working in Java for about 7 years and I've changed my mind about Java application design many times during this period. However, since 2 years ago I think the paradigm adopted to develop applications in my team has been pretty the same and this gives me the enough confidence to work without thinking much about these issues. The main problem I encountered during the past time was the different approaches and technologies (EJBs, WS, SOA, etc). The thing is that none of them gave good guidelines of how to do a good design and addressed mainly performance, portability, interoperability among other issues.
As I said, the big problem here was that good desing guidelines were not given and I think most of the people working in Java appeared to forget that they were working in a Object Oriented Paradigm. In consequence, almost every Java application that I encountered was designed in a procedural way with most of the logic spreading along the different services of the application. This may be a good way to address the low coupling and high cohesion concerns but it throws away most of the object oriented paradigm benefits, such as inheritance, encapsulation and ease of re-usability.
The problem is not entirely of the people that work in Java, but also of the language itself that made difficult to use the paradigm correctly mainly because of the big differences between objects and classes that the language has (in more OO languages like Smalltalk everything is an object, classes are objects).
Furthermore, with the proliferation of IoC containers (Spring, Pico Container, Guice, etc), injecting dependencies to services that will be injected to controllers or managers became a commodity in this kind of applications and Services were converted in the Kings of Objects, leaving the Domain Objects very anemic only working as C structs or simply Database representation of the Model. As I said before, this kind of design is much less Object Oriented than having real domain objects that concentrates their responsibilities and delegates what doesn't concerns them, in other words, a truly object oriented system.
Studing Smalltalk and Python, but also trying to find out a better way to program in Java made me realize that the best thing I could do was to return to the object oriented way of programming and designing software according to this paradigm. At this point some concerns came along, due to the nature of the language is not so easy to convert the domain objects in first class citizens of a system as it should have been always.
There are some ways to overcome this problem, but I explored 2 with great success. The first one is to have Factories for non database objects that need some injection in order to provide them with all the dependencies they should have complemented with DAOs or Generic DAOs (a.k.a. Repositories) that also injects those domain objects that comes from the database. The other way is to use the AOP features of the language and inject those domain objects hanging some VM calls. This is a much more advanced technique and I will address the full explanation of how to do this in Java using Spring, Hibernate and the AspectJ in a later article.

"most of the people working in Java appeared to forget that they were working in a Object Oriented Paradigm. In consequence, almost every Java application that I encountered was designed in a procedural way" <- I couldn't agree more! Great post.
ReplyDelete