From 0a04da1f5877e44526b6ba39a63051140a7af03e Mon Sep 17 00:00:00 2001 From: JanFidor <66260538+JanFidor@users.noreply.github.com> Date: Wed, 26 Oct 2022 19:38:25 +0200 Subject: [PATCH] docs: #590 explanation for a delegation pattern (#2127) --- delegation/README.md | 91 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/delegation/README.md b/delegation/README.md index 8556c5a89..de3011cf2 100644 --- a/delegation/README.md +++ b/delegation/README.md @@ -13,6 +13,97 @@ 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. +## Explanation + +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`. + +```java +public interface Printer { + void print(final String message); +} + +@Slf4j +public class CanonPrinter implements Printer { + @Override + public void print(String message) { + LOGGER.info("Canon Printer : {}", message); + } +} + +@Slf4j +public class EpsonPrinter implements Printer { + @Override + public void print(String message) { + LOGGER.info("Epson Printer : {}", message); + } +} + +@Slf4j +public class HpPrinter implements Printer { + @Override + public void print(String message) { + LOGGER.info("HP Printer : {}", message); + } +} +``` +The `PrinterController` can be used as a `Printer` by delegating any work handled by this +interface to an object implementing it. +```java +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); + } +} +``` + +Now on the client code printer controllers can print messages differently depending on the +object they're delegating that work to. + +```java +private static final String MESSAGE_TO_PRINT = "hello world"; + +var hpPrinterController = new PrinterController(new HpPrinter()); +var canonPrinterController = new PrinterController(new CanonPrinter()); +var epsonPrinterController = new PrinterController(new EpsonPrinter()); + +hpPrinterController.print(MESSAGE_TO_PRINT); +canonPrinterController.print(MESSAGE_TO_PRINT); +epsonPrinterController.print(MESSAGE_TO_PRINT) +``` + +Program output: + +```java +HP Printer : hello world +Canon Printer : hello world +Epson Printer : hello world +``` + ## Class diagram ![alt text](./etc/delegation.png "Delegate")