Delegation in Java with Example

< Previous Next >

OOPS Tutorial

1. Overview

In this article, we will learn the important object-oriented concept - DelegationDelegation means hand over the responsibility for a particular task to another class or method.
It is a technique where an object expresses certain behavior to the outside but in reality delegates responsibility for implementing that behaviour to an associated object.


Use the Delegation in order to achieve the following
  • Reduce the coupling of methods to their class
  • Components that behave identically, but realize that this situation can change in the future.
  • If you need to use functionality in another class but you do not want to change that functionality then use delegation instead of inheritance.

3. Implementation

Example 1: Let's take Ticket Booking example

Step 1: Create TravelBooking interface.
interface TravelBooking {
    public void bookTicket();
Step 2: Let's create TrainBooking class to book train tickets.
class TrainBooking implements TravelBooking {
    public void bookTicket() {
        System.out.println("Train ticket booked");
Step 3: Let's create AirBooking class to book air tickets.
class AirBooking implements TravelBooking {
    public void bookTicket() {
        System.out.println("Flight ticket booked");
Step 4: TicketBokkingByAgent provides an implementation of TravelBooking. But it delegates actual ticket booking to other class at runtime using Polymorphism.
class TicketBookingByAgent implements TravelBooking {

    TravelBooking t;

    public TicketBookingByAgent(TravelBooking t) {
        this.t = t;

    // Delegation --- Here ticket booking responsibility 
    // is delegated to other class using polymorphism
    public void bookTicket() {
Step 5: This is a test class for the delegation and polymorphism example.
public class DelegationDemonstration {

    public static void main(String[] args) {
     // Here TicketBookingByAgent class is internally 
     // delegating train ticket booking responsibility to other class
         TicketBookingByAgent agent = new TicketBookingByAgent(new TrainBooking());

         agent = new TicketBookingByAgent(new AirBooking());

Example 2: Printers Implementation Example

In this example the delegates are CanonPrinter, EpsonPrinter or HpPrinter they all implement Printer. The PrinterController is a delegator class which also implements Printer.
PrinterController is not responsible for the actual desired action but is actually delegated to a helper class either CanonPrinter, EpsonPrinter or HpPrinter. The consumer does not have or require knowledge of the actual class carrying out the action, only the container on which they are calling.
You can observe here the implementation is loosely coupled.

Step 1: First create Printer interface that both the Controller and the Delegate classes will implement.
public interface Printer {
     void print(final String message);
Step 2: Specialised Implementation of Printer for a Canon Printer, in this case, the message to be printed is appended to "Canon Printer: ".
public class CanonPrinter implements Printer {
     private static final Logger LOGGER = LoggerFactory.getLogger(CanonPrinter.class);
     public void print(String message) {
"Canon Printer : {}", message);
Step 3: Specialized Implementation of Printer for an Epson Printer, in this case, the message to be printed is appended to "Epson Printer: ".
public class EpsonPrinter implements Printer {

     private static final Logger LOGGER = LoggerFactory.getLogger(EpsonPrinter.class);
     public void print(String message) {"Epson Printer : {}", message);
Step 4: Specialized Implementation of Printer for an HP Printer, in this case, the message to be printed is appended to "HP Printer: ".
public class HpPrinter implements Printer {

     private static final Logger LOGGER = LoggerFactory.getLogger(HpPrinter.class);
     public void print(String message) {
"HP Printer : {}", message);
Step 5: it's time to implement a Delegator class.
Delegator Class to delegate the implementation of the Printer.
This ensures two things:
  • when the actual implementation of the Printer class changes the delegation will still be operational
  • the actual benefit is observed when there are more than one implementors and they share a delegation control.
public class PrinterController implements Printer {

     private final Printer printer;

     public PrinterController(Printer printer) {
          this.printer = printer;
     public void print(String message) {
Step 6: Let's test the Delegation using the main method.
public class App {

     public static final String MESSAGE_TO_PRINT = "hello world";

      * Program entry point
      * @param args command line args
     public static void main(String[] args) {
          PrinterController hpPrinterController = new PrinterController(new HpPrinter());
          PrinterController canonPrinterController = new PrinterController(new CanonPrinter());
          PrinterController epsonPrinterController = new PrinterController(new EpsonPrinter());


Related Oops Posts

Top Core Java Tutorials

  1. Java Tutorial for Beginners
  2. 50 Java Keywords
  3. JDBC 4.2 Tutorial
  4. All Java/J2EE Tutorial
  5. Java 8 Tutorial
  6. Java Collections Tutorial
  7. Java Exceptions Tutorial
  8. Java Generics Tutorial
  9. Java 8 Stream API Tutorial
  10. Java Wrapper Classes
  11. Java Arrays Guide
  12. Java Multithreading Tutorial
  13. Java Concurrency Tutorial
  14. Oops Concepts Tutorial
  15. Java String API Guide
  16. Java Reflection API Tutorial
  17. Java I/O Tutorial
  18. Date and Time API Tutorial
  19. JUnit 5 Tutorial
  20. JUnit 4 Tutorial
  21. Java XML Tutorial
  22. Google GSON Tutorial

Top Java EE Tutorials

  1. Spring Security Tutorial
  2. RabbitMQ Tutorial
  3. Hibernate ORM 5
  4. Java Persistence API
  5. Spring Boot 2 Tutorial
  6. Spring Core 5 Tutorial
  7. Spring MVC 5 Tutorial
  8. Spring Data JPA Tutorial
  9. Apache HttpClient Tutorial
  10. Spring Framework 5
  11. Apache Maven Tutorial
  12. JAX-RS Tutorial
  13. Jersey Rest Tutorial

Java Library Tutorials

  1. Java API Guides
  2. Java SQL Package Tutorial
  3. All Java/J2EE Tutorial
  4. Java Lang Package Tutorial
  5. Java Util Package Tutorial
  6. Java Lang Reflect Package Tutorial
  7. Java Time Package Tutorial
  8. Java IO Package Tutorial

Top Java Best Practices

  1. Java Enums and Annotations Best Practices
  2. Java Generics Best Practices
  3. JUnit Framework Best Practices
  4. Java Naming Conventions
  5. Single Responsibility Principle
  6. Liskov's Substitution Principle
  7. Interface Segregation Principle
  8. Dependency Inversion Principle
  9. Open Closed Principle
  10. Oops principles in java
  11. Restful API Best Practices
  12. JSP Best Practices
  13. Guide to JDBC Best Practices
  14. Collection Best Practices
  15. String Best Practices in Java
  16. Exception Handling Best Practices
  17. Synchronization Best Practices
  18. Guide to JDBC Best Practices
  19. Serialization Best Practices

The source code of this post is available on GitHub: Object-Oriented Design Guide


  1. class diagram is wrong. +CanonPrinter() in all the different printer class

    1. Class diagram is not wrong. The content CononPrinter is typo in all subclasses.You can fix this.

  2. This typo has fixed , thanks for informing.


Post a Comment