Android programmers, while making software, always tighten up code in a manner that testing and maintainability of the project becomes complicated.Tight coupling is when a group of programming modules are highly dependent on one another. A change in one module usually forces a ripple effect of changes in other modules. This scenario arises when a particular module assumes too many responsibilities, or when one functionality is spread over many modules rather than having its own module.
“Loose Coupling” is a way to overcome this situation, and also a better approach to good programming practice. To achieve loose(low) coupling, we can use Dependency Injection.
What is Dependency Injection?
In simple terms, a dependency is what your module needs to function properly. The intent behind the dependency injection is to decouple modules to the extent that no client code is changed simply because a module it depends on needs to be changed to a different one.
Here are some of the most common pros and cons of a Dependency Injection:
Reduction in dependencies.
Highly reusable code.
Improved testability of codes.
Higher readability of code.
Single responsibility principle can be applied.
It increases complexity, usually when the number of classes is increasing because of the single responsibility principle, which is not always beneficial.
Codes are coupled to the Dependency Injection framework.
Runtime type resolving (slightly) affects the performance.
The programmer needs to write a lot of boilerplate codes to implement the normal dependency to work with modules seamlessly. The boilerplate code contains Factory classes that provide dependencies to each other modules in the project. Developing all these factory classes consumes too much time of developers. If you’re working on a large source code project, then it will be complex to provide this dependency and to manage it manually.
Using Dagger 2 to Achieve Dependency Injection
Based on both the Java Specification Request (JSR) 330 and annotations, Dagger 2 uses code generation. Dagger 2 analyzes dependencies for you and generates code to help wire them together. This code generation process is the part of the compilation process. Remember that Dagger 2 does not inject the dependency; you have to inject the dependency yourself. Dagger 2 can just generate a boilerplate code to inject dependency.
Mode of Injections
Dagger 2 can perform the following modes of injections:
Constructor Injection: Injecting dependency classes to the constructor.
Field Injection: Injecting member variables to the classes.
Method Injection: Injecting parameters to the methods.
There are lots of annotations in Dagger 2 through which you can define your dependency injection. Following are some of the noteworthy pros and cons of Dagger 2:
No more runtime graph composition, Dagger 2 improves performance including the per-request cases.
Traceable; you get a well-generated code that is readily readable and easy-to-follow.
No more reflection as everything is done as concrete calls.
Component implementation requires rebuilding the project to appear, and any injection-related compile errors result in the class disappearing (i.e. not being generated).
The inject() method has a strong type association with the injection target now. It is good for debugging, but it complicates a common practice of injecting from base classes (e.g. base activities, fragments, etc.).
You can find an Android Dagger 2 code sample here. Dependency injection should be use wisely when the system complexity level is high, and changes in the requirement are frequent. It is also useful in the enhancement of product.
How about giving your suggestions or thoughts in the comments box below? I would appreciate your feedback.