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.
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:
Imagine a Chef preparing a meal.
This represents a dependency. The chef depends on the knife only during the cooking process.
Let’s model a simple Printer that depends on a Document to print.
Document
ClassPrinter
ClassHere:
Printer
depends on Document
to complete its work.Printer
does not store or own the Document
—it simply uses it during method execution.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.
Dependency Injection is a technique where you provide dependencies from outside, rather than letting the class create or control them internally.
This allows:
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.