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

This commit is contained in:
JanFidor authored and GitHub committed 2022-10-26 20:38:25 +03:00
1 parent 6e9ea39275
commit 0a04da1f58
1 file changed
+91
+91
View File
@@ -13,6 +13,97 @@ Proxy Pattern
It is a technique where an object expresses certain behavior to the outside but in 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. 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 ## Class diagram
![alt text](./etc/delegation.png "Delegate") ![alt text](./etc/delegation.png "Delegate")