In this article, we will learn how to use and implement the Delegation Pattern in Java with an example.
The advantage of delegation is that it is easy to compose behavior at runtime.
In this example, the delegates are CanonPrinter, EpsonPrinter, and HpPrinter they all implement Printer. The PrinterController is a delegator class that also implements Printer.
PrinterController is not responsible for the actual desired action but is actually delegated to a helper class either CanonPrinter, and 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.
Intent
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.Explanation
Delegation is a way of reusing and extending the behavior of a class. It works writing a new class that incorporates the functionality of the original class by using an instance of the original class and calling its methods.The advantage of delegation is that it is easy to compose behavior at runtime.
Delegation Pattern Implementation Example in Java
Let's take an example of Printers Implementation.In this example, the delegates are CanonPrinter, EpsonPrinter, and HpPrinter they all implement Printer. The PrinterController is a delegator class that also implements Printer.
PrinterController is not responsible for the actual desired action but is actually delegated to a helper class either CanonPrinter, and 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 a 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 CanonPrinter, 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);
@Override
public void print(String message) {
LOGGER.info("Canon Printer : {}", message);
}
}
Step 3: Specialised 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);
@Override
public void print(String message) {
LOGGER.info("Epson Printer : {}", message);
}
}
Step 4: Specialised 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);
@Override
public void print(String message) {
LOGGER.info("HP Printer : {}", message);
}
}
Step 5: it's time to implement the Delegator class.
Delegator Class to delegate the implementation of the Printer.
public class PrinterController implements Printer {
private final Printer printer;
public PrinterController(Printer printer) {
this.printer = printer;
}
@Override
public void print(String message) {
printer.print(message);
}
}
Step 6: Let's test the Delegation pattern 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());
hpPrinterController.print(MESSAGE_TO_PRINT);
canonPrinterController.print(MESSAGE_TO_PRINT);
epsonPrinterController.print(MESSAGE_TO_PRINT);
}
}