AlgoMaster Logo

Dependency

Ashish

Ashish Pratap Singh

What happens when a class needs to use another class for a brief moment to get a job done, without needing to hold onto it forever?

This is the world of Dependency.

Unlike association, aggregation, or composition, dependency is not structural. It does not imply a long-term relationship or shared lifecycle. Instead, it reflects a one-time interaction, often through method parameters, local variables, or return types.

If class A uses class B just to perform a task—not to store or own—that’s a dependency.

1. What is Dependency?

A Dependency exists when one class relies on another to fulfill a responsibility, but does so without retaining a permanent reference to it.

This typically happens when:

  • A class accepts another class as a method parameter.
  • A class instantiates or uses another class inside a method.
  • A class returns an object of another class from a method.

Key Characteristics of Dependency

  • Short-lived: The relationship exists only during method execution.
  • No ownership: The dependent class does not store the other as a field.
  • "Uses-a" relationship: The class uses another to accomplish a task, but does not retain it.

2. Code Example

Let’s model a simple Printer that depends on a Document to print.

Document Class

Printer Class

Here:

  • Printer depends on Document to complete its work.
  • But Printer does not store or own the Document—it simply uses it during method execution.

3. UML Representation

In UML class diagrams, dependency is shown using a dashed arrow pointing from the dependent class to the class it depends on.

This indicates that Printer temporarily uses Document, but does not own or associate with it in a structural sense.

4. Dependency Injection

Dependency Injection is a technique where you provide dependencies from outside, rather than letting the class create or control them internally.

This allows:

  • Better testability (you can inject mocks)
  • Greater modularity (swap implementations)
  • Loose coupling

Example

  • The dependency (Sender) is provided externally, not created internally.
  • NotificationService does not care how messages are sent—it just depends on a Sender interface.

This promotes loose coupling, testability, and open/closed design.