Files
java-design-patterns/dependency-injection
Ilkka Seppälä 6cd2d0353a docs: Content SEO updates (#2990)
* update yaml frontmatter format

* update abstract document

* update abstract factory

* use the new pattern template

* acyclic visitor seo

* adapter seo

* ambassador seo

* acl seo

* aaa seo

* async method invocation seo

* balking seo

* bridge seo

* builder seo

* business delegate and bytecode seo

* caching seo

* callback seo

* chain seo

* update headings

* circuit breaker seo

* client session + collecting parameter seo

* collection pipeline seo

* combinator SEO

* command seo

* cqrs seo

* commander seo

* component seo

* composite seo

* composite entity seo

* composite view seo

* context object seo

* converter seo

* crtp seo

* currying seo

* dao seo

* data bus seo

* data locality seo

* data mapper seo

* dto seo

* decorator seo

* delegation seo

* di seo

* dirty flag seo

* domain model seo

* double buffer seo

* double checked locking seo

* double dispatch seo

* dynamic proxy seo

* event aggregator seo

* event-based asynchronous seo

* eda seo

* event queue seo

* event sourcing seo

* execute around seo

* extension objects seo

* facade seo

* factory seo

* factory kit seo

* factory method seo

* fanout/fanin seo

* feature toggle seo

* filterer seo

* fluent interface seo

* flux seo

* flyweight seo

* front controller seo

* function composition seo

* game loop seo

* gateway seo

* guarded suspension seo

* half-sync/half-async seo

* health check seo

* hexagonal seo

* identity map seo

* intercepting filter seo

* interpreter seo

* iterator seo

* layers seo

* lazy loading seo

* leader election seo

* leader/followers seo

* lockable object seo

* rename and add seo for marker interface

* master-worker seo

* mediator seo

* memento seo

* metadata mapping seo

* microservice aggregator seo

* api gw seo

* microservices log aggregration seo

* mvc seo

* mvi seo

* mvp seo

* mvvm seo

* monad seo

* monitor seo

* monostate seo

* multiton seo

* mute idiom seo

* naked objects & notification seo

* null object seo

* object mother seo

* object pool seo

* observer seo

* optimistic locking seo

* page controller seo

* page object seo

* parameter object seo

* partial response seo

* pipeline seo

* poison pill seo

* presentation model seo

* private class data seo

* producer-consumer seo

* promise seo

* property seo

* prototype seo

* proxy seo

* queue-based load leveling seo

* reactor seo

* registry seo

* repository seo

* RAII seo

* retry seo

* role object seo

* saga seo

* separated interface seo

* serialized entity seo

* serialized lob seo

* servant seo

* server session seo

* service layer seo

* service locator seo

* service to worker seo

* sharding seo

* single table inheritance seo

* singleton seo

* spatial partition seo

* special case seo

* specification seo

* state seo

* step builder seo

* strangler seo

* strategy seo

* subclass sandbox seo

* table module seo

* template method seo

* throttling seo

* tolerant reader seo

* trampoline seo

* transaction script seo

* twin seo

* type object seo

* unit of work seo

* update method seo

* value object seo

* version number seo

* virtual proxy seo

* visitor seo

* seo enhancements

* seo improvements

* SEO enhancements

* SEO improvements

* SEO additions

* SEO improvements

* more SEO improvements

* rename hexagonal + SEO improvements

* SEO improvements

* more SEO stuff

* SEO improvements

* SEO optimizations

* SEO enhancements

* enchance SEO

* improve SEO

* SEO improvements

* update headers
2024-06-08 19:54:44 +03:00
..
2024-05-23 18:40:52 +03:00
2022-09-14 23:22:24 +05:30
2024-06-08 19:54:44 +03:00

title, shortTitle, description, category, language, tag
title shortTitle description category language tag
Dependency Injection Pattern in Java: Boosting Maintainability with Loose Coupling Dependency Injection Learn about the Dependency Injection design pattern. Explore its benefits, real-world examples, class diagrams, and best practices for implementation in Java. Creational en
Decoupling
Dependency management
Inversion of control

Also known as

  • Inversion of Control (IoC)
  • Dependency Inversion

Intent of Dependency Injection Design Pattern

To decouple the creation of object dependencies from their usage, allowing for more flexible and testable code.

Detailed Explanation of Dependency Injection Pattern with Real-World Examples

Real-world example

Imagine a high-end restaurant where the chef needs various ingredients to prepare dishes. Instead of the chef personally going to different suppliers for each ingredient, a trusted supplier delivers all the required fresh ingredients daily. This allows the chef to focus on cooking without worrying about sourcing the ingredients.

In the Dependency Injection design pattern, the trusted supplier acts as the "injector," providing the necessary dependencies (ingredients) to the chef (object). The chef can then use these dependencies without knowing where they came from, ensuring a clean separation between the creation and use of dependencies. This setup enhances efficiency, flexibility, and maintainability in the kitchen, much like in a software system.

In plain words

Dependency Injection separates the creation of the client's dependencies from its own behavior.

Wikipedia says

In software engineering, dependency injection is a technique in which an object receives other objects that it depends on. These other objects are called dependencies.

Programmatic Example of Dependency Injection Pattern in Java

The old wizard likes to fill his pipe and smoke tobacco once in a while. However, he doesn't want to depend on a single tobacco brand only but likes to be able to enjoy them all interchangeably.

Let's first introduce the Tobacco interface and the concrete brands.


@Slf4j
public abstract class Tobacco {

    public void smoke(Wizard wizard) {
        LOGGER.info("{} smoking {}", wizard.getClass().getSimpleName(),
                this.getClass().getSimpleName());
    }
}

public class SecondBreakfastTobacco extends Tobacco {
}

public class RivendellTobacco extends Tobacco {
}

public class OldTobyTobacco extends Tobacco {
}

Next here's the Wizard class hierarchy.

public interface Wizard {

    void smoke();
}

public class AdvancedWizard implements Wizard {

    private final Tobacco tobacco;

    public AdvancedWizard(Tobacco tobacco) {
        this.tobacco = tobacco;
    }

    @Override
    public void smoke() {
        tobacco.smoke(this);
    }
}

Finally, we can show how easy it is to give the old wizard any brand of tobacco.

public static void main(String[] args) {
    var simpleWizard = new SimpleWizard();
    simpleWizard.smoke();

    var advancedWizard = new AdvancedWizard(new SecondBreakfastTobacco());
    advancedWizard.smoke();

    var advancedSorceress = new AdvancedSorceress();
    advancedSorceress.setTobacco(new SecondBreakfastTobacco());
    advancedSorceress.smoke();

    var injector = Guice.createInjector(new TobaccoModule());
    var guiceWizard = injector.getInstance(GuiceWizard.class);
    guiceWizard.smoke();
}

The program output:

11:54:05.205 [main] INFO com.iluwatar.dependency.injection.Tobacco -- SimpleWizard smoking OldTobyTobacco
11:54:05.207 [main] INFO com.iluwatar.dependency.injection.Tobacco -- AdvancedWizard smoking SecondBreakfastTobacco
11:54:05.207 [main] INFO com.iluwatar.dependency.injection.Tobacco -- AdvancedSorceress smoking SecondBreakfastTobacco
11:54:05.308 [main] INFO com.iluwatar.dependency.injection.Tobacco -- GuiceWizard smoking RivendellTobacco

Detailed Explanation of Dependency Injection Pattern with Real-World Examples

Dependency Injection

When to Use the Dependency Injection Pattern in Java

  • When aiming to reduce the coupling between classes and increase the modularity of the application.
  • In scenarios where the object creation process is complex or should be separated from the class usage.
  • In applications requiring easier unit testing by allowing dependencies to be mocked or stubbed.
  • Within frameworks or libraries that manage object lifecycles and dependencies, such as Spring or Jakarta EE (formerly Java EE).

Real-World Applications of Dependency Injection Pattern in Java

  • Frameworks like Spring, Jakarta EE, and Google Guice use Dependency Injection (DI) extensively to manage component lifecycles and dependencies.
  • Desktop and web applications that require flexible architecture with easily interchangeable components.

Benefits and Trade-offs of Dependency Injection Pattern

Benefits:

  • Enhances modularity and separation of concerns.
  • Simplifies unit testing by allowing for easy mocking of dependencies.
  • Increases flexibility and maintainability by promoting loose coupling.

Trade-offs:

  • Can introduce complexity in the configuration, especially in large projects.
  • Might increase the learning curve for developers unfamiliar with Dependency Injection patterns or frameworks.
  • Requires careful management of object lifecycles and scopes.
  • Factory Method and Abstract Factory: Used to create instances that the DI mechanism will inject.
  • Service Locator: An alternative to DI for locating services or components, though it does not decouple the lookup process as effectively as DI.
  • Singleton: Often used in conjunction with DI to provide a single instance of a service across the application.

References and Credits