Proxy Pattern
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.
Real-world example
Imagine that we have adventurers who fight monsters with different weapons depending on their abilities and skills. We must be able to equip them with different ones without having to modify their source code for each one. The delegation pattern makes it possible by delegating the dynamic work to a specific object implementing an interface with relevant methods.
Wikipedia says
In object-oriented programming, delegation refers to evaluating a member (property or method) of one object (the receiver) in the context of another original object (the sender). Delegation can be done explicitly, by passing the sending object to the receiving object, which can be done in any object-oriented language; or implicitly, by the member lookup rules of the language, which requires language support for the feature.
Programmatic Example
We have an interface Printer
and three implementations CanonPrinter
, EpsonPrinter
and HpPrinter
.
1public interface Printer {
2 void print(final String message);
3}
4
5@Slf4j
6public class CanonPrinter implements Printer {
7 @Override
8 public void print(String message) {
9 LOGGER.info("Canon Printer : {}", message);
10 }
11}
12
13@Slf4j
14public class EpsonPrinter implements Printer {
15 @Override
16 public void print(String message) {
17 LOGGER.info("Epson Printer : {}", message);
18 }
19}
20
21@Slf4j
22public class HpPrinter implements Printer {
23 @Override
24 public void print(String message) {
25 LOGGER.info("HP Printer : {}", message);
26 }
27}
The PrinterController
can be used as a Printer
by delegating any work handled by this
interface to an object implementing it.
1public class PrinterController implements Printer {
2
3 private final Printer printer;
4
5 public PrinterController(Printer printer) {
6 this.printer = printer;
7 }
8
9 @Override
10 public void print(String message) {
11 printer.print(message);
12 }
13}
Now on the client code printer controllers can print messages differently depending on the object they’re delegating that work to.
1private static final String MESSAGE_TO_PRINT = "hello world";
2
3var hpPrinterController = new PrinterController(new HpPrinter());
4var canonPrinterController = new PrinterController(new CanonPrinter());
5var epsonPrinterController = new PrinterController(new EpsonPrinter());
6
7hpPrinterController.print(MESSAGE_TO_PRINT);
8canonPrinterController.print(MESSAGE_TO_PRINT);
9epsonPrinterController.print(MESSAGE_TO_PRINT)
Program output:
1HP Printer : hello world
2Canon Printer : hello world
3Epson Printer : hello world
Use the Delegate pattern in order to achieve the following