Back to Relationships: Association, Aggregation, Composition
Q3Question 3 of 3

What is the delegation pattern?

Key Concepts
  • Delegation forwards method calls to a contained delegate object rather than inheriting behavior from a parent
  • Delegation gives control: the wrapper exposes only the methods it wants (unlike inheritance which exposes all)
  • Delegation gives flexibility: the delegate can be swapped at runtime (unlike inheritance which is fixed at compile time)
  • Delegation gives safety: logic can be added before and after the delegated call (logging, validation, caching)
  • The Decorator pattern is delegation where the wrapper implements the same interface as the delegate
  • In Spring, @Transactional proxies use delegation: the proxy forwards the call and adds transaction management

Definition

Delegation holds a delegate and forwards selected calls. Inheritance inherits all parent methods. Delegation gives control (expose what you want), flexibility (swap delegate), and safety (add logic around calls).

The delegation pattern forwards method calls to a contained delegate object rather than inheriting behavior.

  • Control: the wrapper exposes only the methods it wants. Inheritance exposes all parent public methods, even unwanted ones.
  • Flexibility: the delegate can be swapped at runtime via constructor injection. Inheritance is fixed at compile time.
  • Enhancement: the wrapper can add logic before and after the delegated call (logging, validation, caching).
  • Decorator pattern: a specific form of delegation where the wrapper implements the same interface as the delegate.
  • Spring example: @Transactional proxies use delegation: the proxy forwards the call to the real bean and adds transaction management around it.

Inheritance: SavingsAccount IS-A Account at National Bank of India and automatically gets all of Account's public methods, even unwanted ones like transferInternational(). Delegation: SavingsAccountService HAS-A AccountOperations delegate and forwards deposit() and withdraw() but hides transferInternational(). The service controls what is visible.

Understanding the Concepts

What is the delegation pattern?

Delegation is composition over inheritance applied as a concrete pattern.

How does delegation differ from inheritance?

JAVA
// Inheritance: exposes everything from parent
public class Account {
    public void deposit(java.math.BigDecimal amount) { /* ... */ }
    public void withdraw(java.math.BigDecimal amount) { /* ... */ }
    public void transferInternational(String country, java.math.BigDecimal amount) { /* ... */ }
}
public class SavingsAccount extends Account {
    // Inherits ALL: deposit, withdraw, transferInternational
    // transferInternational() is unwanted for savings but it is inherited and public.
}

// Delegation: forwards only what you choose
public class SavingsAccountService {
    private final Account delegate;

    public SavingsAccountService(Account delegate) { this.delegate = delegate; }

    public void deposit(java.math.BigDecimal amount) {
        if (amount.compareTo(new java.math.BigDecimal("10000000")) > 0) {
            throw new IllegalArgumentException("Savings deposit limit: Rs.1 crore");
        }
        delegate.deposit(amount); // delegates the actual work
    }

    public void withdraw(java.math.BigDecimal amount) {
        delegate.withdraw(amount); // delegates
    }

    // transferInternational: deliberately NOT forwarded.
    // Caller cannot call savingsService.transferInternational().
}

What are the three benefits?

JAVA
// Benefit 1: Control (expose only what makes sense)
// Inheritance: all parent methods visible. Cannot hide transferInternational.
// Delegation: forward deposit + withdraw. Hide everything else.

// Benefit 2: Enhancement (decorate before/after)
public void deposit(java.math.BigDecimal amount) {
    log.info("Before deposit: {}", amount);
    validate(amount);
    delegate.deposit(amount); // delegate
    notifyCustomer("Deposited Rs." + amount);
}

// Benefit 3: Swappability (change delegate at runtime)
public class FlexibleService {
    private AccountOperations delegate;
    public void setDelegate(AccountOperations newDelegate) {
        this.delegate = newDelegate; // swap at runtime
    }
}
// Production: PostgresAccountOps. Testing: MockAccountOps.

How does delegation compare to inheritance?

| Aspect | Inheritance | Delegation |
|--------|------------|------------|
| API exposure | All parent methods | Only forwarded methods |
| Flexibility | Fixed at compile time | Swappable at runtime |
| Enhancement | Override + super.method() (fragile) | Add logic around delegate call |
| Coupling | Tight (child depends on parent internals) | Loose (depends on interface) |

What patterns use delegation?

  • Decorator: wrapper implements same interface as delegate, adds behavior.
  • Adapter: wrapper translates between incompatible interfaces.
  • Proxy: wrapper controls access to the delegate (Spring @Transactional).

What should a senior engineer know?

  • In Spring, all @Transactional proxies use delegation: the proxy intercepts the call, starts a transaction, delegates to the real bean, and commits or rolls back.
  • Kotlin has built-in delegation syntax: class Stack(private val list: MutableList) : MutableList by list.
  • Project Lombok's @Delegate annotation generates delegation boilerplate automatically.

Visual Overview

DIAGRAM
  INHERITANCE
  ┌────────────────────────┐
  │ Account                 │
  │ deposit()               │
  │ withdraw()              │
  │ transferInternational() │ <- unwanted but inherited
  └──────────┬─────────────┘
             │ extends
  ┌──────────┴─────────────┐
  │ SavingsAccount          │
  │ ALL methods visible     │
  └────────────────────────┘

  DELEGATION
  ┌────────────────────────┐
  │ SavingsAccountService   │
  │ deposit() -> delegate   │ forwarded
  │ withdraw() -> delegate  │ forwarded
  │                         │
  │ transferInternational() │ NOT forwarded (hidden)
  │ ┌──────────────────┐   │
  │ │ Account delegate  │   │ private field
  │ └──────────────────┘   │
  └────────────────────────┘

Key Takeaway

The delegation pattern forwards method calls to a contained delegate object instead of inheriting behavior. The wrapper class holds a reference to the delegate and controls which methods are forwarded, unlike inheritance where all parent public methods are automatically exposed. Delegation provides three advantages: control (expose only deposit and withdraw, hide transferInternational), enhancement (add validation and logging around each delegated call), and flexibility (swap the delegate at runtime for testing or different implementations).

Delegation is composition over inheritance applied as a pattern. The Decorator pattern is a specific form where the wrapper implements the same interface as the delegate. In Spring, @Transactional proxies use delegation: the proxy forwards the call to the real bean, adding transaction management around the delegation.

Remember one sentence: delegation forwards selected calls to a contained object, giving control over what is exposed, flexibility to swap at runtime, and the ability to add logic around each call.

---

Share
Use ← → arrow keys to navigate