diff --git a/website/src/daily-emails/2022-12-08.md b/website/src/daily-emails/2022-12-08.md new file mode 100644 index 00000000..c77c78ed --- /dev/null +++ b/website/src/daily-emails/2022-12-08.md @@ -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.