docs(daily-email): add 2022-12-08
This commit is contained in:
parent
88a330de84
commit
b752fd4900
64
website/src/daily-emails/2022-12-08.md
Normal file
64
website/src/daily-emails/2022-12-08.md
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
---
|
||||||
|
title: >
|
||||||
|
The Decorator design pattern
|
||||||
|
pubDate: 2022-12-08
|
||||||
|
permalink: >
|
||||||
|
archive/2022/12/08/the-decorator-design-pattern
|
||||||
|
tags:
|
||||||
|
- design-patterns
|
||||||
|
---
|
||||||
|
|
||||||
|
Decorator is a structural design pattern that allows you to add extra functionality, such as if you want to add caching or logging to a service, without changing the original class.
|
||||||
|
|
||||||
|
As long as a class implements an Interface, it can be decorated.
|
||||||
|
|
||||||
|
For example, if I have this PHP interface:
|
||||||
|
|
||||||
|
```php
|
||||||
|
interface DoesSomething
|
||||||
|
{
|
||||||
|
public function doSomething(): void;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
I could have this class that does something:
|
||||||
|
|
||||||
|
```php
|
||||||
|
final class FirstClass implements DoesSomething
|
||||||
|
{
|
||||||
|
public function doSomething(): void
|
||||||
|
{
|
||||||
|
// Does something.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If I need to do something else, like caching or logging the result, I can decorate it.
|
||||||
|
|
||||||
|
To do this, I need another class that implements the same interface and inject the original version.
|
||||||
|
|
||||||
|
```php
|
||||||
|
final class SecondClass implements DoesSomething
|
||||||
|
{
|
||||||
|
public function __constuct(
|
||||||
|
private DoesSomething $originalClass
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public function doSomething()
|
||||||
|
{
|
||||||
|
// Do something else before.
|
||||||
|
|
||||||
|
$this->originalClass->doSomething();
|
||||||
|
|
||||||
|
// Do something else afterwards.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Within the new class, the methods can be overridden, extra functionality can be added, and the original method can be run to execute the original functionality.
|
||||||
|
|
||||||
|
As the two classes implement the same interface, I can swap between different versions and decorate multiple times if needed.
|
||||||
|
|
||||||
|
This a pattern that I used recently to extend a service that retrieved some data from an API and saved it to a file, to change some arguments and do more work with it.
|
||||||
|
|
||||||
|
The original class was unchanged, the new class was minimal and easy to understand as it only had a single responsibility, and if I needed to switch back to the original version, I could easily do that.
|
Loading…
Reference in a new issue