Dependency
Uses-a relationship
Overview
Dependency is the weakest relationship between classes. It exists when one class uses another class temporarily - typically as a method parameter, local variable, or return type. The dependent class doesn't hold a reference to the other class as a member.
Dependencies should be minimized as they create coupling between classes.
Key Concepts
Weakest form of relationship
Temporary usage - not stored as field
Used as parameter, local variable, or return type
Represented by dashed arrow in UML
Changes in one class may affect the other
Code Example
1// Dependency: PaymentService depends on PaymentGateway
2// but doesn't own it - receives it temporarily
3
4public interface PaymentGateway {
5 boolean processPayment(double amount);
6}
7
8public class StripeGateway implements PaymentGateway {
9 @Override
10 public boolean processPayment(double amount) {
11 System.out.println("Processing $" + amount + " via Stripe");
12 return true;
13 }
14}
15
16public class Order {
17 private String orderId;
18 private double amount;
19
20 public Order(String orderId, double amount) {
21 this.orderId = orderId;
22 this.amount = amount;
23 }
24
25 public double getAmount() { return amount; }
26}
27
28public class PaymentService {
29 // No PaymentGateway field - dependency, not association
30
31 // Depends on Order and PaymentGateway via method parameters
32 public boolean processOrderPayment(Order order, PaymentGateway gateway) {
33 System.out.println("Processing payment for order");
34 return gateway.processPayment(order.getAmount());
35 }
36
37 // Depends on Order as return type
38 public Order createOrder(String id, double amount) {
39 return new Order(id, amount);
40 }
41}
42
43// Another example with utility dependency
44public class ReportGenerator {
45 // Depends on DateFormatter but doesn't own it
46 public String generateReport(List<Sale> sales, DateFormatter formatter) {
47 StringBuilder report = new StringBuilder();
48 report.append("Sales Report - ").append(formatter.formatDate(new Date()));
49 for (Sale sale : sales) {
50 report.append("
51").append(sale.toString());
52 }
53 return report.toString();
54 }
55}
56
57// Usage
58public class Main {
59 public static void main(String[] args) {
60 PaymentService service = new PaymentService();
61 Order order = service.createOrder("ORD-001", 99.99);
62 PaymentGateway gateway = new StripeGateway();
63
64 // Gateway is passed in - dependency, not owned
65 service.processOrderPayment(order, gateway);
66 }
67}PaymentService uses PaymentGateway temporarily through method parameters. It doesn't store or own the gateway.
When to Use
When a class only needs another temporarily
For utility classes and helpers
When injecting dependencies through methods
For callbacks and event handlers
Best Practices
- 1.
Minimize dependencies - they create coupling
- 2.
Use interfaces for dependencies (Dependency Inversion)
- 3.
Inject dependencies rather than creating them
- 4.
Keep dependency relationships unidirectional
💡 Interview Tips
Explain it's the weakest relationship
No permanent reference stored
Know UML notation (dashed arrow)
Distinguish from association (which stores reference)
Discuss how to reduce coupling via interfaces