I just started to use Guice.
When I am using Guice my application classes get loosely coupled.
Does using Google Guice make the code less readable, less clear, more complicated to understand and debug?
How is your experience with it?
If someone is not familiar with dependency injection in general then yes, I think it can make code more difficult to follow and comprehend...at first. For example, the first time I worked with Spring, I was a little confused to say the least. However, once you wrap your head around the concept of injecting beans and such, it makes sense.
Good design is paramount, and DI is critical to loose coupling and testability.
My experience has been uniformly positive. My code is much more readable; it's astronomically easier to test and maintain. Loose coupling is the point.
Using dependency injection sensibly, whether via Guice or otherwise, can make code much easier to test and to keep clean and loosely coupled. It makes the use of test doubles (mock objects etc) much easier.
Done badly, or taken to extremes, it can make the system almost incomprehensible - even though each class may be clear in isolation, it can be very difficult to tell what the assembly of classes does (especially if massive XML config files are involved!). Some systems seem to use the DI configuration as a programming language in its own right, which can quickly become unmanageable.
Which on is easier to read?
A:
public class ServiceCaller {
private String url;
private Service service;
public A {
url = System.getProperty("url);
Hashtable env = ...;
Context ctx = new InitialContext(...)
service = ctx.lookup(...)
}
public String getValue() {
return service.getValue();
} ...
or
public class ServiceCaller {
private Service service;
@Inject
public ServiceCaller(Service service) {
this.service = service;
}
public String getValue() { ...}
If you are not used to DI, you will probably say "#1", since you can read all the implementation, and know exactly what is happening, what the service is and so on. But the problem is: looking at the classes contract from the outside, you have no idea what is happening inside. #2 clearly states: "Give me a Service-instance, and I will give you a value. All you have to do, is to believe that there is a hidden mechanism that will provide this service-Instance". (Hidden=hidden in plain sight, you will need to have a "getproperty-getcontext-getService-Module" in your code)
So in my opinion: DI is easier to read (use constructor based injection whenever possible). Its easier to test, and some might say, that the best documentation is a well written, working Test. You just need a little faith to believe that there will be a service instance ...