Home  >  Article  >  Backend Development  >  Detailed description of PHP adapter pattern (with code examples)

Detailed description of PHP adapter pattern (with code examples)

藏色散人
藏色散人forward
2023-04-05 15:36:482171browse

This article brings you relevant knowledge about PHP. It mainly talks about the PHP adapter mode and code examples. Friends who are interested can take a look below. I hope it will be helpful to you.

Detailed description of PHP adapter pattern (with code examples)

PHP Adapter Pattern Explanation and Code Examples

Adapter is a structural design Pattern, which enables incompatible objects to cooperate with each other.

The adapter can serve as a wrapper between two objects. It will receive a call to one object and convert it into a format and interface recognized by the other object.

Complexity: ******

Popularity: ******

Usage examples: The adapter pattern is very common in PHP code. Systems based on some legacy code often use this pattern. In this case, adapters allow legacy code to work with modern classes.

Identification method: Adapters can be identified through constructors that take instances of different abstract or interface types as parameters. When any method of the adapter is called, it converts the parameters into the appropriate format and then directs the call to one or more methods in its encapsulated object.

  • Real World Example

Adapters allow you to use classes from third-party or legacy systems even if they are incompatible with your code. For example, you can create a series of special wrappers to adapt the calls made by the application to the interface and format required by the third-party class, without having to rewrite the application's notification interface to support each third-party service ( Such as DingTalk, WeChat, SMS or any other service).

index.php: Real world example

<?php

namespace RefactoringGuru\Adapter\RealWorld;

/**
 * The Target interface represents the interface that your application&#39;s classes
 * already follow.
 */
interface Notification
{
    public function send(string $title, string $message);
}

/**
 * Here&#39;s an example of the existing class that follows the Target interface.
 *
 * The truth is that many real apps may not have this interface clearly defined.
 * If you&#39;re in that boat, your best bet would be to extend the Adapter from one
 * of your application&#39;s existing classes. If that&#39;s awkward (for instance,
 * SlackNotification doesn&#39;t feel like a subclass of EmailNotification), then
 * extracting an interface should be your first step.
 */
class EmailNotification implements Notification
{
    private $adminEmail;

    public function __construct(string $adminEmail)
    {
        $this->adminEmail = $adminEmail;
    }

    public function send(string $title, string $message): void
    {
        mail($this->adminEmail, $title, $message);
        echo "Sent email with title &#39;$title&#39; to &#39;{$this->adminEmail}&#39; that says &#39;$message&#39;.";
    }
}

/**
 * The Adaptee is some useful class, incompatible with the Target interface. You
 * can&#39;t just go in and change the code of the class to follow the Target
 * interface, since the code might be provided by a 3rd-party library.
 */
class SlackApi
{
    private $login;
    private $apiKey;

    public function __construct(string $login, string $apiKey)
    {
        $this->login = $login;
        $this->apiKey = $apiKey;
    }

    public function logIn(): void
    {
        // Send authentication request to Slack web service.
        echo "Logged in to a slack account &#39;{$this->login}&#39;.\n";
    }

    public function sendMessage(string $chatId, string $message): void
    {
        // Send message post request to Slack web service.
        echo "Posted following message into the &#39;$chatId&#39; chat: &#39;$message&#39;.\n";
    }
}

/**
 * The Adapter is a class that links the Target interface and the Adaptee class.
 * In this case, it allows the application to send notifications using Slack
 * API.
 */
class SlackNotification implements Notification
{
    private $slack;
    private $chatId;

    public function __construct(SlackApi $slack, string $chatId)
    {
        $this->slack = $slack;
        $this->chatId = $chatId;
    }

    /**
     * An Adapter is not only capable of adapting interfaces, but it can also
     * convert incoming data to the format required by the Adaptee.
     */
    public function send(string $title, string $message): void
    {
        $slackMessage = "#" . $title . "# " . strip_tags($message);
        $this->slack->logIn();
        $this->slack->sendMessage($this->chatId, $slackMessage);
    }
}

/**
 * The client code can work with any class that follows the Target interface.
 */
function clientCode(Notification $notification)
{
    // ...

    echo $notification->send("Website is down!",
        "<strong style=&#39;color:red;font-size: 50px;&#39;>Alert!</strong> " .
        "Our website is not responding. Call admins and bring it up!");

    // ...
}

echo "Client code is designed correctly and works with email notifications:\n";
$notification = new EmailNotification("developers@example.com");
clientCode($notification);
echo "\n\n";


echo "The same client code can work with other classes via adapter:\n";
$slackApi = new SlackApi("example.com", "XXXXXXXX");
$notification = new SlackNotification($slackApi, "Example.com Developers");
clientCode($notification);

Output.txt: Execution result

Client code is designed correctly and works with email notifications:
Sent email with title &#39;Website is down!&#39; to &#39;developers@example.com&#39; that says &#39;<strong style=&#39;color:red;font-size: 50px;&#39;>Alert!</strong> Our website is not responding. Call admins and bring it up!&#39;.
The same client code can work with other classes via adapter:
Logged in to a slack account &#39;example.com&#39;.
Posted following message into the &#39;Example.com Developers&#39; chat: &#39;#Website is down!# Alert! Our website is not responding. Call admins and bring it up!&#39;.
  • Conceptual example

This example illustrates the structure of the Adapter design pattern and focuses on answering the following questions:

  • What classes does it consist of?
  • What roles do these classes play?
  • How do the elements in the pattern relate to each other?

After understanding the structure of this pattern, you can more easily understand the following real-world PHP application cases.

index.php: Concept example

<?php

namespace RefactoringGuru\Adapter\Conceptual;

/**
 * The Target defines the domain-specific interface used by the client code.
 */
class Target
{
    public function request(): string
    {
        return "Target: The default target&#39;s behavior.";
    }
}

/**
 * The Adaptee contains some useful behavior, but its interface is incompatible
 * with the existing client code. The Adaptee needs some adaptation before the
 * client code can use it.
 */
class Adaptee
{
    public function specificRequest(): string
    {
        return ".eetpadA eht fo roivaheb laicepS";
    }
}

/**
 * The Adapter makes the Adaptee&#39;s interface compatible with the Target&#39;s
 * interface.
 */
class Adapter extends Target
{
    private $adaptee;

    public function __construct(Adaptee $adaptee)
    {
        $this->adaptee = $adaptee;
    }

    public function request(): string
    {
        return "Adapter: (TRANSLATED) " . strrev($this->adaptee->specificRequest());
    }
}

/**
 * The client code supports all classes that follow the Target interface.
 */
function clientCode(Target $target)
{
    echo $target->request();
}

echo "Client: I can work just fine with the Target objects:\n";
$target = new Target();
clientCode($target);
echo "\n\n";

$adaptee = new Adaptee();
echo "Client: The Adaptee class has a weird interface. See, I don&#39;t understand it:\n";
echo "Adaptee: " . $adaptee->specificRequest();
echo "\n\n";

echo "Client: But I can work with it via the Adapter:\n";
$adapter = new Adapter($adaptee);
clientCode($adapter);

Output.txt: Execution result

Client: I can work just fine with the Target objects:
Target: The default target&#39;s behavior.

Client: The Adaptee class has a weird interface. See, I don&#39;t understand it:
Adaptee: .eetpadA eht fo roivaheb laicepS

Client: But I can work with it via the Adapter:
Adapter: (TRANSLATED) Special behavior of the Adaptee.

Recommended study:《PHP video tutorial

The above is the detailed content of Detailed description of PHP adapter pattern (with code examples). For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:juejin.im. If there is any infringement, please contact admin@php.cn delete