docs: #590 explanation for a delegation pattern (#2127)

This commit is contained in:
JanFidor
2022-10-26 19:38:25 +02:00
committed by GitHub
parent 6e9ea39275
commit 0a04da1f58
+91
View File
@@ -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")