Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for PHP Design Patterns - Adapter
Fabio Hiroki
Fabio Hiroki

Posted on • Edited on

     

PHP Design Patterns - Adapter

Users are loving your application and you want to give them more joy. What could bring them more happiness than email notifications?

Someone feeling joy

Let's welcome our users!

We want our users to feel good after signing up in our application, so why not send an welcome email? You already know a reliable email service provider that has a SDK you can install using Composer, so everything seems lovely so far.

Unfortunately, when integrating the SDK you notice the classes doesn't fit very well.SignUpService only has the recipient email and the content, andThirdPartyEmailClient expects configuration parameters.

Our hypotethical SDK has the following structure:

classThirdPartyEmailClient{publicfunction__construct(privatestring$apiKey,privatestring$region,){}publicfunctionsendEmail(string$recipient,string$content,):void{echosprintf("Using apiKey %s and region %s",$this->apiKey,$this->region);echosprintf("Sending email to %s and content %s",$recipient,$content);}}
Enter fullscreen modeExit fullscreen mode

Diagram of interaction between SignUpService and ThirdPartyEmailClient

Make it work

IfThirdPartyEmailClient is asking forapiKey andregion, let's fullfil its wishes. We could simply do it by injecting both parameters onSignUpService, or even by hardcoding them. It wouldn't be a problem until you need to send an email after user updated his profile that is implemeted onProfileService class.

Well, you're just figuring out how to make it work because you're a good professional and want to get things done, then you just copy and paste the hardcoded parameters fromSignUpService. Good job!

Something feels wrong

Gif of someone with insomnia

That night you couldn't sleep because of that code duplication. You're also exposing theapiKey everywhere. How to solve this problem?

Make it right

Then you remember of this pattern calledAdapter. It is supposed to make classes that have incompatible interfaces work together. First step is creating the interface expected by client:

interfaceEmailSenderAdapter{publicfunctionsendEmail(string$recipient,string$content):void;}
Enter fullscreen modeExit fullscreen mode

Now you just need to wrapThirdPartyEmailClient in a new class that implements the previous interface:

finalclassThirdPartyEmailSenderAdapterimplementsEmailSenderAdapter{publicfunction__construct(privateThirdPartyEmailClient$emailClient){}publicfunctionsendEmail(string$recipient,string$content):void{$this->emailClient->sendEmail($recipient,$content);}}
Enter fullscreen modeExit fullscreen mode

SignUpService is happy now because it has a friend that understands its language.

Diagram after the adapter implementation

And now to make it even better, you decide to add a unit test!

Testing

publicfunctiontestThirdPartyEmailSenderAdapterAdapterUsesCorrectClient():void{$emailClient=$this->createMock(ThirdPartyEmailClient::class);$emailAdapter=newThirdPartyEmailSenderAdapter($emailClient);$emailClient->expects($this->once())->method('sendEmail')->with('email@email.com','I love design patterns');$emailAdapter->sendEmail('email@email.com','I love design patterns');}
Enter fullscreen modeExit fullscreen mode

You did it!

Happy programmer

Your classes are seamless integrated, tested and if you need to change the email service provider you just need to wrap the new client to implement theEmailSenderAdapter and you can switch an old interface for the new one. Congratulations.

Final code on Github.


Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

I write about thriving in your software development career by embracing a balanced and fulfilling approach to work
  • Work
    Senior Software Engineer at Mollie
  • Joined

More fromFabio Hiroki

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp