Does Loose Coupling Always Result In Code Duplication?
Join the DZone community and get the full member experience.Join For Free
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]
Opinions expressed by DZone contributors are their own.