From 0a51e0ce54ee994cdfd221beb8b39fbee421d9f2 Mon Sep 17 00:00:00 2001 From: Fabio Hiroki Date: Wed, 27 Oct 2021 21:35:28 +0200 Subject: [PATCH 1/5] Add adapter --- app/structural/adapter/AwsSesAdapter.php | 17 ++++++++++++ app/structural/adapter/EmailSenderAdapter.php | 10 +++++++ app/structural/adapter/FakeAwsSesClient.php | 23 ++++++++++++++++ tests/structural/adapter/AdapterTest.php | 27 +++++++++++++++++++ 4 files changed, 77 insertions(+) create mode 100644 app/structural/adapter/AwsSesAdapter.php create mode 100644 app/structural/adapter/EmailSenderAdapter.php create mode 100644 app/structural/adapter/FakeAwsSesClient.php create mode 100644 tests/structural/adapter/AdapterTest.php diff --git a/app/structural/adapter/AwsSesAdapter.php b/app/structural/adapter/AwsSesAdapter.php new file mode 100644 index 0000000..88333ce --- /dev/null +++ b/app/structural/adapter/AwsSesAdapter.php @@ -0,0 +1,17 @@ +awsSesClient->sendEmail($subject, $recipient, $content); + } +} \ No newline at end of file diff --git a/app/structural/adapter/EmailSenderAdapter.php b/app/structural/adapter/EmailSenderAdapter.php new file mode 100644 index 0000000..27de8a2 --- /dev/null +++ b/app/structural/adapter/EmailSenderAdapter.php @@ -0,0 +1,10 @@ +apiKey, $this->region); + echo sprintf("Sending email to %s with subject %s and content %s", $subject, $recipient, $content); + } +} \ No newline at end of file diff --git a/tests/structural/adapter/AdapterTest.php b/tests/structural/adapter/AdapterTest.php new file mode 100644 index 0000000..8203738 --- /dev/null +++ b/tests/structural/adapter/AdapterTest.php @@ -0,0 +1,27 @@ +createMock(FakeAwsSesClient::class); + + $emailAdapter = new AwsSesAdapter($awsClient); + + $awsClient->expects($this->once()) + ->method('sendEmail'); + + $emailAdapter->sendEmail( + 'I love design patterns', + 'email@emal.com', + 'I really do.'); + } +} \ No newline at end of file From bfd22cf87e0e48a01476a95e2904d618345a7507 Mon Sep 17 00:00:00 2001 From: Fabio Hiroki Date: Wed, 27 Oct 2021 21:38:26 +0200 Subject: [PATCH 2/5] fix lint --- app/structural/adapter/AwsSesAdapter.php | 2 +- app/structural/adapter/EmailSenderAdapter.php | 2 +- app/structural/adapter/FakeAwsSesClient.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/structural/adapter/AwsSesAdapter.php b/app/structural/adapter/AwsSesAdapter.php index 88333ce..71f4792 100644 --- a/app/structural/adapter/AwsSesAdapter.php +++ b/app/structural/adapter/AwsSesAdapter.php @@ -14,4 +14,4 @@ public function sendEmail(string $subject, string $recipient, string $content): { $this->awsSesClient->sendEmail($subject, $recipient, $content); } -} \ No newline at end of file +} diff --git a/app/structural/adapter/EmailSenderAdapter.php b/app/structural/adapter/EmailSenderAdapter.php index 27de8a2..97d710e 100644 --- a/app/structural/adapter/EmailSenderAdapter.php +++ b/app/structural/adapter/EmailSenderAdapter.php @@ -7,4 +7,4 @@ interface EmailSenderAdapter { public function sendEmail(string $subject, string $recipient, string $content): void; -} \ No newline at end of file +} diff --git a/app/structural/adapter/FakeAwsSesClient.php b/app/structural/adapter/FakeAwsSesClient.php index ed98aa2..9b88387 100644 --- a/app/structural/adapter/FakeAwsSesClient.php +++ b/app/structural/adapter/FakeAwsSesClient.php @@ -20,4 +20,4 @@ public function sendEmail( echo sprintf("Using apiKey %s and region %s", $this->apiKey, $this->region); echo sprintf("Sending email to %s with subject %s and content %s", $subject, $recipient, $content); } -} \ No newline at end of file +} From 126ff3716290590d2e95182f0c546d79d97b8fa7 Mon Sep 17 00:00:00 2001 From: Fabio Hiroki Date: Sat, 30 Oct 2021 10:18:25 +0200 Subject: [PATCH 3/5] add diagram --- app/structural/adapter/AwsSesAdapter.php | 17 ----------------- app/structural/adapter/EmailAdapter.php | 10 ++++++++++ app/structural/adapter/EmailSenderAdapter.php | 10 ---------- .../adapter/ThirdPartyEmailAdapter.php | 17 +++++++++++++++++ ...sSesClient.php => ThirdPartyEmailClient.php} | 5 ++--- app/structural/adapter/docs/diagrams.md | 1 + tests/structural/adapter/AdapterTest.php | 11 +++++------ 7 files changed, 35 insertions(+), 36 deletions(-) delete mode 100644 app/structural/adapter/AwsSesAdapter.php create mode 100644 app/structural/adapter/EmailAdapter.php delete mode 100644 app/structural/adapter/EmailSenderAdapter.php create mode 100644 app/structural/adapter/ThirdPartyEmailAdapter.php rename app/structural/adapter/{FakeAwsSesClient.php => ThirdPartyEmailClient.php} (70%) create mode 100644 app/structural/adapter/docs/diagrams.md diff --git a/app/structural/adapter/AwsSesAdapter.php b/app/structural/adapter/AwsSesAdapter.php deleted file mode 100644 index 71f4792..0000000 --- a/app/structural/adapter/AwsSesAdapter.php +++ /dev/null @@ -1,17 +0,0 @@ -awsSesClient->sendEmail($subject, $recipient, $content); - } -} diff --git a/app/structural/adapter/EmailAdapter.php b/app/structural/adapter/EmailAdapter.php new file mode 100644 index 0000000..4818c2f --- /dev/null +++ b/app/structural/adapter/EmailAdapter.php @@ -0,0 +1,10 @@ +emailClient->sendEmail($recipient, $content); + } +} diff --git a/app/structural/adapter/FakeAwsSesClient.php b/app/structural/adapter/ThirdPartyEmailClient.php similarity index 70% rename from app/structural/adapter/FakeAwsSesClient.php rename to app/structural/adapter/ThirdPartyEmailClient.php index 9b88387..ac1c236 100644 --- a/app/structural/adapter/FakeAwsSesClient.php +++ b/app/structural/adapter/ThirdPartyEmailClient.php @@ -4,7 +4,7 @@ namespace app\structural\adapter; -class FakeAwsSesClient +class ThirdPartyEmailClient { public function __construct( private string $apiKey, @@ -13,11 +13,10 @@ public function __construct( } public function sendEmail( - string $subject, string $recipient, string $content, ): void { echo sprintf("Using apiKey %s and region %s", $this->apiKey, $this->region); - echo sprintf("Sending email to %s with subject %s and content %s", $subject, $recipient, $content); + echo sprintf("Sending email to %s with and content %s", $recipient, $content); } } diff --git a/app/structural/adapter/docs/diagrams.md b/app/structural/adapter/docs/diagrams.md new file mode 100644 index 0000000..8010384 --- /dev/null +++ b/app/structural/adapter/docs/diagrams.md @@ -0,0 +1 @@ +[![](https://mermaid.ink/img/eyJjb2RlIjoic2VxdWVuY2VEaWFncmFtXG4gICAgU2lnblVwU2VydmljZS0tPj5UaGlyZFBhcnR5RW1haWxDbGllbnQ6IEkgd2FudCB0byBzZW5kIGFuIGVtYWlsIVxuICAgIFRoaXJkUGFydHlFbWFpbENsaWVudC0tPj5TaWduVXBTZXJ2aWNlOiBDb29sLCBnaXZlIG1lIGZpcnN0IGFuIGFwaUtleSBhbmQgYSByZWdpb24hXG4gICAgU2lnblVwU2VydmljZS0tPj5UaGlyZFBhcnR5RW1haWxDbGllbnQ6IEJ1dCBJIGp1c3QgaGF2ZSB0aGUgcmVjaXBpZW50IGFuZCBjb250ZW50ID0vXG4gICAgICAgICAgICAiLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9LCJ1cGRhdGVFZGl0b3IiOmZhbHNlLCJhdXRvU3luYyI6dHJ1ZSwidXBkYXRlRGlhZ3JhbSI6ZmFsc2V9)](https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoic2VxdWVuY2VEaWFncmFtXG4gICAgU2lnblVwU2VydmljZS0tPj5UaGlyZFBhcnR5RW1haWxDbGllbnQ6IEkgd2FudCB0byBzZW5kIGFuIGVtYWlsIVxuICAgIFRoaXJkUGFydHlFbWFpbENsaWVudC0tPj5TaWduVXBTZXJ2aWNlOiBDb29sLCBnaXZlIG1lIGZpcnN0IGFuIGFwaUtleSBhbmQgYSByZWdpb24hXG4gICAgU2lnblVwU2VydmljZS0tPj5UaGlyZFBhcnR5RW1haWxDbGllbnQ6IEJ1dCBJIGp1c3QgaGF2ZSB0aGUgcmVjaXBpZW50IGFuZCBjb250ZW50ID0vXG4gICAgICAgICAgICAiLCJtZXJtYWlkIjoie1xuICBcInRoZW1lXCI6IFwiZGVmYXVsdFwiXG59IiwidXBkYXRlRWRpdG9yIjpmYWxzZSwiYXV0b1N5bmMiOnRydWUsInVwZGF0ZURpYWdyYW0iOmZhbHNlfQ) \ No newline at end of file diff --git a/tests/structural/adapter/AdapterTest.php b/tests/structural/adapter/AdapterTest.php index 8203738..1b83328 100644 --- a/tests/structural/adapter/AdapterTest.php +++ b/tests/structural/adapter/AdapterTest.php @@ -4,24 +4,23 @@ namespace structural\adapter; -use app\structural\adapter\AwsSesAdapter; -use app\structural\adapter\FakeAwsSesClient; +use app\structural\adapter\ThirdPartyEmailAdapter; +use app\structural\adapter\ThirdPartyEmailClient; use PHPUnit\Framework\TestCase; final class AdapterTest extends TestCase { public function testAwsAdapterUsesCorrectClient(): void { - $awsClient = $this->createMock(FakeAwsSesClient::class); + $awsClient = $this->createMock(ThirdPartyEmailClient::class); - $emailAdapter = new AwsSesAdapter($awsClient); + $emailAdapter = new ThirdPartyEmailAdapter($awsClient); $awsClient->expects($this->once()) ->method('sendEmail'); $emailAdapter->sendEmail( 'I love design patterns', - 'email@emal.com', - 'I really do.'); + 'email@emal.com'); } } \ No newline at end of file From 9c037539c494c0b233a9454e1646b1e954105553 Mon Sep 17 00:00:00 2001 From: Fabio Hiroki Date: Sun, 31 Oct 2021 18:19:39 +0100 Subject: [PATCH 4/5] Rename --- .../adapter/{EmailAdapter.php => EmailSenderAdapter.php} | 2 +- ...PartyEmailAdapter.php => ThirdPartyEmailSenderAdapter.php} | 2 +- tests/structural/adapter/AdapterTest.php | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) rename app/structural/adapter/{EmailAdapter.php => EmailSenderAdapter.php} (83%) rename app/structural/adapter/{ThirdPartyEmailAdapter.php => ThirdPartyEmailSenderAdapter.php} (81%) diff --git a/app/structural/adapter/EmailAdapter.php b/app/structural/adapter/EmailSenderAdapter.php similarity index 83% rename from app/structural/adapter/EmailAdapter.php rename to app/structural/adapter/EmailSenderAdapter.php index 4818c2f..61ab0d9 100644 --- a/app/structural/adapter/EmailAdapter.php +++ b/app/structural/adapter/EmailSenderAdapter.php @@ -4,7 +4,7 @@ namespace app\structural\adapter; -interface EmailAdapter +interface EmailSenderAdapter { public function sendEmail(string $recipient, string $content): void; } diff --git a/app/structural/adapter/ThirdPartyEmailAdapter.php b/app/structural/adapter/ThirdPartyEmailSenderAdapter.php similarity index 81% rename from app/structural/adapter/ThirdPartyEmailAdapter.php rename to app/structural/adapter/ThirdPartyEmailSenderAdapter.php index f27da2f..a60f285 100644 --- a/app/structural/adapter/ThirdPartyEmailAdapter.php +++ b/app/structural/adapter/ThirdPartyEmailSenderAdapter.php @@ -4,7 +4,7 @@ namespace app\structural\adapter; -final class ThirdPartyEmailAdapter implements EmailAdapter +final class ThirdPartyEmailSenderAdapter implements EmailSenderAdapter { public function __construct(private ThirdPartyEmailClient $emailClient) { diff --git a/tests/structural/adapter/AdapterTest.php b/tests/structural/adapter/AdapterTest.php index 1b83328..ae8e37c 100644 --- a/tests/structural/adapter/AdapterTest.php +++ b/tests/structural/adapter/AdapterTest.php @@ -4,7 +4,7 @@ namespace structural\adapter; -use app\structural\adapter\ThirdPartyEmailAdapter; +use app\structural\adapter\ThirdPartyEmailSenderAdapter; use app\structural\adapter\ThirdPartyEmailClient; use PHPUnit\Framework\TestCase; @@ -14,7 +14,7 @@ public function testAwsAdapterUsesCorrectClient(): void { $awsClient = $this->createMock(ThirdPartyEmailClient::class); - $emailAdapter = new ThirdPartyEmailAdapter($awsClient); + $emailAdapter = new ThirdPartyEmailSenderAdapter($awsClient); $awsClient->expects($this->once()) ->method('sendEmail'); From 1c529879910f70c097239d19a4d862c5bfc0b322 Mon Sep 17 00:00:00 2001 From: Fabio Hiroki Date: Mon, 1 Nov 2021 18:39:48 +0100 Subject: [PATCH 5/5] add test --- .../adapter/ThirdPartyEmailClient.php | 2 +- app/structural/adapter/docs/diagrams.md | 4 +++- tests/structural/adapter/AdapterTest.php | 21 +++++++++++++------ 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/app/structural/adapter/ThirdPartyEmailClient.php b/app/structural/adapter/ThirdPartyEmailClient.php index ac1c236..dd65db2 100644 --- a/app/structural/adapter/ThirdPartyEmailClient.php +++ b/app/structural/adapter/ThirdPartyEmailClient.php @@ -17,6 +17,6 @@ public function sendEmail( string $content, ): void { echo sprintf("Using apiKey %s and region %s", $this->apiKey, $this->region); - echo sprintf("Sending email to %s with and content %s", $recipient, $content); + echo sprintf("Sending email to %s and content %s", $recipient, $content); } } diff --git a/app/structural/adapter/docs/diagrams.md b/app/structural/adapter/docs/diagrams.md index 8010384..b8ed0fa 100644 --- a/app/structural/adapter/docs/diagrams.md +++ b/app/structural/adapter/docs/diagrams.md @@ -1 +1,3 @@ -[![](https://mermaid.ink/img/eyJjb2RlIjoic2VxdWVuY2VEaWFncmFtXG4gICAgU2lnblVwU2VydmljZS0tPj5UaGlyZFBhcnR5RW1haWxDbGllbnQ6IEkgd2FudCB0byBzZW5kIGFuIGVtYWlsIVxuICAgIFRoaXJkUGFydHlFbWFpbENsaWVudC0tPj5TaWduVXBTZXJ2aWNlOiBDb29sLCBnaXZlIG1lIGZpcnN0IGFuIGFwaUtleSBhbmQgYSByZWdpb24hXG4gICAgU2lnblVwU2VydmljZS0tPj5UaGlyZFBhcnR5RW1haWxDbGllbnQ6IEJ1dCBJIGp1c3QgaGF2ZSB0aGUgcmVjaXBpZW50IGFuZCBjb250ZW50ID0vXG4gICAgICAgICAgICAiLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9LCJ1cGRhdGVFZGl0b3IiOmZhbHNlLCJhdXRvU3luYyI6dHJ1ZSwidXBkYXRlRGlhZ3JhbSI6ZmFsc2V9)](https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoic2VxdWVuY2VEaWFncmFtXG4gICAgU2lnblVwU2VydmljZS0tPj5UaGlyZFBhcnR5RW1haWxDbGllbnQ6IEkgd2FudCB0byBzZW5kIGFuIGVtYWlsIVxuICAgIFRoaXJkUGFydHlFbWFpbENsaWVudC0tPj5TaWduVXBTZXJ2aWNlOiBDb29sLCBnaXZlIG1lIGZpcnN0IGFuIGFwaUtleSBhbmQgYSByZWdpb24hXG4gICAgU2lnblVwU2VydmljZS0tPj5UaGlyZFBhcnR5RW1haWxDbGllbnQ6IEJ1dCBJIGp1c3QgaGF2ZSB0aGUgcmVjaXBpZW50IGFuZCBjb250ZW50ID0vXG4gICAgICAgICAgICAiLCJtZXJtYWlkIjoie1xuICBcInRoZW1lXCI6IFwiZGVmYXVsdFwiXG59IiwidXBkYXRlRWRpdG9yIjpmYWxzZSwiYXV0b1N5bmMiOnRydWUsInVwZGF0ZURpYWdyYW0iOmZhbHNlfQ) \ No newline at end of file +[![](https://mermaid.ink/img/eyJjb2RlIjoic2VxdWVuY2VEaWFncmFtXG4gICAgU2lnblVwU2VydmljZS0tPj5UaGlyZFBhcnR5RW1haWxDbGllbnQ6IEkgd2FudCB0byBzZW5kIGFuIGVtYWlsIVxuICAgIFRoaXJkUGFydHlFbWFpbENsaWVudC0tPj5TaWduVXBTZXJ2aWNlOiBDb29sLCBnaXZlIG1lIGZpcnN0IGFuIGFwaUtleSBhbmQgYSByZWdpb24hXG4gICAgU2lnblVwU2VydmljZS0tPj5UaGlyZFBhcnR5RW1haWxDbGllbnQ6IEJ1dCBJIGp1c3QgaGF2ZSB0aGUgcmVjaXBpZW50IGFuZCBjb250ZW50ID0vXG4gICAgICAgICAgICAiLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9LCJ1cGRhdGVFZGl0b3IiOmZhbHNlLCJhdXRvU3luYyI6dHJ1ZSwidXBkYXRlRGlhZ3JhbSI6ZmFsc2V9)](https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoic2VxdWVuY2VEaWFncmFtXG4gICAgU2lnblVwU2VydmljZS0tPj5UaGlyZFBhcnR5RW1haWxDbGllbnQ6IEkgd2FudCB0byBzZW5kIGFuIGVtYWlsIVxuICAgIFRoaXJkUGFydHlFbWFpbENsaWVudC0tPj5TaWduVXBTZXJ2aWNlOiBDb29sLCBnaXZlIG1lIGZpcnN0IGFuIGFwaUtleSBhbmQgYSByZWdpb24hXG4gICAgU2lnblVwU2VydmljZS0tPj5UaGlyZFBhcnR5RW1haWxDbGllbnQ6IEJ1dCBJIGp1c3QgaGF2ZSB0aGUgcmVjaXBpZW50IGFuZCBjb250ZW50ID0vXG4gICAgICAgICAgICAiLCJtZXJtYWlkIjoie1xuICBcInRoZW1lXCI6IFwiZGVmYXVsdFwiXG59IiwidXBkYXRlRWRpdG9yIjpmYWxzZSwiYXV0b1N5bmMiOnRydWUsInVwZGF0ZURpYWdyYW0iOmZhbHNlfQ) + +[![](https://mermaid.ink/img/eyJjb2RlIjoic2VxdWVuY2VEaWFncmFtXG4gICAgU2lnblVwU2VydmljZS0tPj5UaGlyZFBhcnR5RW1haWxTZW5kZXJBZGFwdGVyOiBJIHdhbnQgdG8gc2VuZCBhbiBlbWFpbCFcbiAgICBUaGlyZFBhcnR5RW1haWxTZW5kZXJBZGFwdGVyLS0-PlNpZ25VcFNlcnZpY2U6IEkganVzdCBuZWVkIGEgcmVjaWNwaWVudCBhbmQgdGhlIGNvbnRlbnQhXG4gICAgU2lnblVwU2VydmljZS0tPj5UaGlyZFBhcnR5RW1haWxTZW5kZXJBZGFwdGVyOiBPaCwgdGhhdCdzIGV4YWN0bHkgd2hhdCBJIGhhdmUhXG4gICAgVGhpcmRQYXJ0eUVtYWlsU2VuZGVyQWRhcHRlci0tPj5UaGlyZFBhcnR5RW1haWxDbGllbnQ6IFBsZWFzZSBzZW5kIHRoaXMgZW1haWxcbiAgICAgICAgICAgICIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0In0sInVwZGF0ZUVkaXRvciI6ZmFsc2UsImF1dG9TeW5jIjp0cnVlLCJ1cGRhdGVEaWFncmFtIjpmYWxzZX0)](https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoic2VxdWVuY2VEaWFncmFtXG4gICAgU2lnblVwU2VydmljZS0tPj5UaGlyZFBhcnR5RW1haWxTZW5kZXJBZGFwdGVyOiBJIHdhbnQgdG8gc2VuZCBhbiBlbWFpbCFcbiAgICBUaGlyZFBhcnR5RW1haWxTZW5kZXJBZGFwdGVyLS0-PlNpZ25VcFNlcnZpY2U6IEkganVzdCBuZWVkIGEgcmVjaWNwaWVudCBhbmQgdGhlIGNvbnRlbnQhXG4gICAgU2lnblVwU2VydmljZS0tPj5UaGlyZFBhcnR5RW1haWxTZW5kZXJBZGFwdGVyOiBPaCwgdGhhdCdzIGV4YWN0bHkgd2hhdCBJIGhhdmUhXG4gICAgVGhpcmRQYXJ0eUVtYWlsU2VuZGVyQWRhcHRlci0tPj5UaGlyZFBhcnR5RW1haWxDbGllbnQ6IFBsZWFzZSBzZW5kIHRoaXMgZW1haWxcbiAgICAgICAgICAgICIsIm1lcm1haWQiOiJ7XG4gIFwidGhlbWVcIjogXCJkZWZhdWx0XCJcbn0iLCJ1cGRhdGVFZGl0b3IiOmZhbHNlLCJhdXRvU3luYyI6dHJ1ZSwidXBkYXRlRGlhZ3JhbSI6ZmFsc2V9) \ No newline at end of file diff --git a/tests/structural/adapter/AdapterTest.php b/tests/structural/adapter/AdapterTest.php index ae8e37c..15ac706 100644 --- a/tests/structural/adapter/AdapterTest.php +++ b/tests/structural/adapter/AdapterTest.php @@ -10,17 +10,26 @@ final class AdapterTest extends TestCase { - public function testAwsAdapterUsesCorrectClient(): void + public function testThirdPartyEmailSenderAdapterAdapterUsesCorrectClient(): void { - $awsClient = $this->createMock(ThirdPartyEmailClient::class); + $emailClient = $this->createMock(ThirdPartyEmailClient::class); - $emailAdapter = new ThirdPartyEmailSenderAdapter($awsClient); + $emailAdapter = new ThirdPartyEmailSenderAdapter($emailClient); - $awsClient->expects($this->once()) + $emailClient->expects($this->once()) ->method('sendEmail'); $emailAdapter->sendEmail( - 'I love design patterns', - 'email@emal.com'); + 'email@email.com', + 'I love design patterns'); + } + + public function testThirdPartyClient(): void + { + $emailClient = new ThirdPartyEmailClient('apiKey', 'region'); + $emailClient->sendEmail('email@email.com', 'I love design patterns'); + + $this->expectOutputRegex('/Using apiKey apiKey and region region/'); + $this->expectOutputRegex('/Sending email to email@email.com and content I love design patterns/'); } } \ No newline at end of file