16

Design Patterns in PHP 8: Adapter

 3 years ago
source link: https://dev.to/zhukmax/design-patterns-in-php-8-adapter-41hi
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Design Patterns in PHP 8 (4 Part Series)

Hi!
Suppose we decide to create a function that will notify the account manager about a new registered user. We create this function, which will call the universal send() function for sending messages, which takes two strings - the subject of the message and its text.

function messageAboutNewClient(): void
{
    send('New client', 'We have a new client...');
}

It will be better make it more abstract and OOP-like. For that we can do special interface and expect that the class implementing it will take all the necessary work on itself. This will allow us to send messages in the way we want. Suppose, when registering in one way, we send messages by email, and in another way, registration causes sending messages, for example, by SMS.

function messageAboutNewClient(NotificationInterface $notification): void
{
    $notification->send('New client', 'We have a new client...');
}

Just like this. And it can implement interface different ways in each class, no matter how many there are. Now we are not tied to a single function for sending messages and can substitute any class that implements the desired interface. Let's prepare this interface.

interface NotificationInterface
{
    public function send(string $title, string $message): void;
}

The send() function from the beginning of the article implemented sending letters using the standard PHP mail method, let's create a class that implements our interface based on this function.

class EmailNotification implements NotificationInterface
{
    public function __construct(public readonly string $adminEmail)
    {
    }

    public function send(string $title, string $message): void
    {
        // Standard php function for sending emails
        mail($this->adminEmail, $title, $message);
    }
}

And this is how you can send messages about new customers:

$notification = new EmailNotification('[email protected]');
messageAboutNewClient($notification);

Some time ago, I wrote a library for sending SMS messages, which I posted on github under a free license. I would like to include it in the project. But there is a problem: the library works a little differently than our interface, it doesn't even have a send method. And here the Adapter design pattern comes to the rescue, which allows you to painlessly connect the library with its interfaces and our project using a special layer class.

Let's create an adapter class that will implement NotificationInterface while working with the library in accordance with the documentation.

use Exception;
use Zhukmax\Smsc\Api;

class SmsNotification implements NotificationInterface
{
    private Api $service;
    private array $phones;

    /**
     * @param array $phones
     */
    public function setPhones(array $phones): void
    {
        $this->phones = $phones;
    }

    /**
     * @throws Exception
     */
    public function __construct(array $config, string $from)
    {
        $this->service = new Api(
            $config['login'],
            $config['password'],
            [
                'https' => $config['https'],
                'charset' => $config['charset'],
                'from' => $from,
                'post' => true
            ]
        );
    }

    public function send(string $title, string $message): void
    {
        $this->service->sendSms($this->phones, `$title $message`);
    }
}

Now we can call the messageAboutNewClient function for sending messages about new clients without changing anything in it. Since the library can throw exceptions, we will wrap everything with try / catch.

try {
    $notification = new SmsNotification($config, '[email protected]');
    $notification->setPhones([+19001234567]);
    messageAboutNewClient($notification);
} catch (Exception $e) {
    // ...
}

© Photo by Tangerine Chan on Unsplash


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK