Java Champion / JavaOne Rockstar Adam Bien (adam-bien.com) is a self-employed consultant, lecturer, software architect, developer, and author in the enterprise Java sector. He is also the author of several books and articles on Java and Java EE technology, as well as distributed Java programming. adam has posted 59 posts at DZone. View Full User Profile

Does Loose Coupling Always Result In Code Duplication?

08.26.2009
| 6484 views |
  • submit to reddit

Per its very nature - it has to. Loose coupling aims for making functional units independent of each other. This is only possible with the introduction of a level of indirection. The thinnest possible layer is an ordinary Java interface, the heaviest one - a WSDL. The mechanics of decoupling are simple as well: a neutral contract is the boundary between the provider and the consumer.

In JDBC the java.sql.Connection is used by the application developer and is implemented by the database vendor. Both rely on this neutral contract. But the interface itself could be already considered as code duplication. You could actually work directly with the vendor implementation - what was very common before the advent of JDBC. Funny enough: at the JDK 1.1 time it was sometimes hard to introduce JDBC, because some developers argued that it is too abstract and indirect :-).

Although old, JDBC is a perfect example for efficient and pragmatic API-SPI design (except the SQLExceptions :-)). The JDBC API is the canonical representation of the functionality and both parties used it from the opposite "directions".

JDBC is Java, but you get considerably more duplication with something like CORBA. Then you will get an IDL file, which describes the contract, then a Java interface what is generated from the IDL for the stub and the same interface with skeletons for the server. You could even go one step further and use instead of binary protocols like IIOP, SOAP and WSDL. This could be considered as CORBA over ASCII :-).

Even something lightweight and pragmatic as REST causes duplication. You are exposing a resource with Java methods, with JAXB DTOs as parameters. Those resources are mapped to URL and the DTOs to payload.

On the client side you have to parse the JSON, XML or other formats into DTOs for easier consumption. The client side DTOs and the corresponding serverside parameters are surprisingly similar if not identical (except perhaps their package declarations)

Things get a little bit strange in enterprise or corporate projects, where architects try to decouple modules introducing an artificial level of indirection. It becomes especially "funny", if the client and sever are both developed in Java and the duplication becomes obvious. But the real problem is the shift of the canonical representation from the contract to the client or serverside. In vast majority of all cases not the contract, but the database or the UI become the canonical "master". Everything else has to be derived from the single "truth". Ruby On Rails folks built a whole framework around this principle and try to leverage as much as possible from the database and its meta data. RoR is said to work well :-).

Loose coupling is only healthy and easy to maintain, in case the service user must not be derived from the resource behind the service provider. You can change then the resource and even the service implementation without breaking the contract or the client.

A typical RFE, like the introduction of an additional text control to a form, changes the service, the indirection and the UI - and so all participants. Such RFEs can be more efficiently implemented without any indirections - in contrary you should try to derive as much as possible from the canonical representation of the domain object / entity.

[Data Transfer Objects are often introduced to increase decoupling, see page 153 in "Real World Java EE Patterns - Rethinking Best Practices" and Premature Encapsulation Is the Root of All Evil, Page 253]

From http://www.adam-bien.com

Published at DZone with permission of its author, adam bien.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

Comments

Ricky Clarkson replied on Wed, 2009/08/26 - 7:21am

Good idea for an article, lousy execution.

Steven Gertiser replied on Wed, 2009/08/26 - 8:48am in response to: Ricky Clarkson

I wonder if you are referring to the writing style, Ricky. Adam is not, I think, a native English speaker, so maybe we here should all cut each other some slack.

Rigel Kentaurus replied on Wed, 2009/08/26 - 9:47am in response to: Steven Gertiser

I'd have to agree with Ricky, the topic is a very interesting one, but I didn't feel like I learnt something from the article, it looked more like a random rant like the ones I use to blog ;)

The loose coupling can be indeed very useful. Having work in a project where we had dependencies, and those dependencies had dependencies, and those dependecies also needed more jars... and some of them were actually circular so you couldn't just use a single component without having to include everything in the project, I got a renewed respect for duplicating some bits of code. It's ok, maybe, to include a commons-logging or log4j, but it's awful to include all the commons-util classes if you only want to use one method of one class... I could deal with a local class with that single method just for reducing the size of my packaged application a bit (In some scenarios I care about that, in others not so much)

Sometimes duplication is necessary, I mean, serializing my jave bean, passing it to json, then reading the json data and instantiating the javascritp object is something that I do on a daily basis now.

That could make sense, but how about serializing a java bean,  parsing it to an xml document, sending it over the wire, parsing the xml document back, and instantiating another java bean that is suspiciously identical to the first bean in the first place. That is where things start to get weird. I could just serialize the java object all together and instantiate the object with the same class definition in the other site... why bother with the xml generation and parsing, why bother having two identical classes?

 But the point is I need both of them, because in the event that the maintainer of the project wants to change his class, he can easily do so, without affecting the XML that is now our convention or interface. In the other scenario he could never, ever, change his Java class or I would get horrible exceptions on the other side. Debugging those errors is hell. Just because of that, we do everything with xml or json instead of just serializing java objects, even when sending information from a java program to a java program. Remembering that you shouldn't touch a class definition just because someone has the same definition elsewhere in another jar is not something you want to do. In this case, some duplication is actually good.

Stevi Deter replied on Wed, 2009/08/26 - 10:56am

This is definitely a case where explicit examples would be useful. Show me actual cases of code duplication caused by loose coupling.

adam bien replied on Wed, 2009/08/26 - 3:38pm in response to: Stevi Deter

@Stevideter, Just try to build a Java client for this REST-service. You will have to parse the JSON / XML data - probably into an OrderDTO. It will be similar, if not identical to the Order-Entity.... Thats duplication. You could use an Java-Interface with the Order entity directly. This would have other consequences, but would be DRY.

Mark Unknown replied on Wed, 2009/08/26 - 9:11pm

No, loose coupling does not always result in more code. It seldom does. The problem is people misintepret loose coupling. With the demise of EJB1/2 DTOs are an antipattern.  They are not needed to "separate the layers". That was never their true purpose. 

 On the other hand, more code does seem to result when mixing platforms. For instance Java on the Server and Flex on the client. If you use something like Gilead, "DTOs" (they really are NOT DTOs) are not needed, but you will end up duplicating business logic. If not, you'll more than like be using more bandwidth.  So, for you JavaFX haters, that is why it is valuable to the Java platform.

Mark Unknown replied on Wed, 2009/08/26 - 9:19pm in response to: adam bien

@Adam, if you are using Java on the server, then use the Java object on the client.

Also, You don't deserialize a XML into a Java object. You deserialize a DTO bytestream into DTO and then recreate the Domain object from it.

 Again, your example is [more than likely] a cross platform issue, not loose coupling.

 

Manjuka Soysa replied on Wed, 2009/08/26 - 10:25pm in response to: adam bien

I think you are talking about generated client code being similar to the server data model? If it is generated, who cares if it is duplicate? You are not going to maintain it seperately.

But at a more general level, you don't have to have any data model on the client side, you can just use XML. So really the problem has nothing to do with loose coupling. The advantage of generating client code is that it will do type checking, and it is easier to code.

adam bien replied on Thu, 2009/08/27 - 1:23am in response to: Manjuka Soysa

Hi Manjuka, whether the code is generated, or manually crafted - it is duplication. This post is not a criticism, rather than an observation. >But at a more general level, you don't have to have any data model on the client side, you can just >use XML. So really the problem has nothing to do with loose coupling. Indirectly it has. You will have to serialize a Java class into XML on the server and deserialize it on the client. The deserialized representation should be similar to the serverside code :-)

Ricky Clarkson replied on Thu, 2009/08/27 - 10:33am in response to: Steven Gertiser

I was referring to the content, rather than the style.

adam bien replied on Fri, 2009/08/28 - 2:24am in response to: Ricky Clarkson

O.k - how about: that?

Alessandro Santini replied on Sun, 2009/08/30 - 12:56pm in response to: Mark Unknown

DTOs an antipattern? Oh dear, that is a nice one. I have heard too many saying this and then having to deal with Flex clients receiving model objects with unneeded relationships or, even worse, lazy relationships not being sent at all.

Even in the case of purely JEE applications with the usual web interface, DTOs are still a very good pattern - information hiding is a good practice, as well as keeping user session's data at the minimum.

Last but not least, maintaining DTOs is not that expensive and mapping them back/forth is easy as well. The Dozer framework is a good hand at this.

Ciao Alessandro

Jeroen Wenting replied on Mon, 2009/08/31 - 12:24am

Code duplication at some level is unavoidable. After all, calling the same method on the same class twice effectively could be considered code duplication if you're looking at your code through a microscope.
And it's not necessarilly a bad thing (tm) either. As are all things in life, you have to weigh the benefits against the drawbacks of everything you do. A few lines of code duplicated in places to avoid a lot of heavy method calls to overly complex and highly generic methods (which would often be the alternative) if a tradeoff anyone should be willing to make.

Stevi Deter replied on Thu, 2009/09/03 - 11:58am in response to: adam bien

Adam,

Actually, I just wrote a REST service using RESTEasy that uses Castor to directly marshal and unmarshal my domain classes, which took remarkably little code to write, precisely because we made the decision to not repeat ourselves.

For me, the moral of the story is to always ask "do I need this very similar code?" Loose coupling and a  lean code base are, in my experience, very complimentar pursuits, not exclusive. 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.