ホームページ  >  記事  >  バックエンド開発  >  PHP アダプター パターンの詳細な説明 (コード例付き)

PHP アダプター パターンの詳細な説明 (コード例付き)

藏色散人
藏色散人転載
2023-04-05 15:36:482171ブラウズ

この記事では、PHP に関する関連知識を紹介します。主に PHP アダプター モードとコード例について説明します。興味のある方は以下を参照してください。お役に立てれば幸いです。

PHP アダプター パターンの詳細な説明 (コード例付き)

PHP アダプター パターンの説明とコード例

Adapter は構造設計パターンです。これにより、互換性のないオブジェクトが相互に連携できるようになります。

アダプターは 2 つのオブジェクト間のラッパーとして機能し、一方のオブジェクトへの呼び出しを受け取り、もう一方のオブジェクトが認識する形式とインターフェイスに変換します。

複雑さ: ******

人気度: ******

使用法例: アダプター パターンは、PHP コードで非常に一般的です。一部のレガシー コードに基づくシステムでは、このパターンがよく使用されます。この場合、アダプターを使用すると、レガシー コードが最新のクラスで動作できるようになります。

識別方法: アダプターは、さまざまな抽象型またはインターフェイス型のインスタンスをパラメーターとして受け取るコンストラクターを通じて識別できます。アダプターのメソッドが呼び出されると、パラメーターが適切な形式に変換され、カプセル化されたオブジェクト内の 1 つ以上のメソッドに呼び出しが指示されます。

  • 実際の例

アダプターを使用すると、コードと互換性がない場合でも、サードパーティまたはレガシー システムのクラスを使用できます。たとえば、各サードパーティ サービスをサポートするためにアプリケーションの通知インターフェイスを書き直すことなく、アプリケーションによる呼び出しをサードパーティ クラスで必要なインターフェイスと形式に適合させる一連の特別なラッパーを作成できます ( DingTalk、WeChat、SMS、またはその他のサービス)。

index.php: 実際の例

<?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: 実行結果

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;.
  • 概念的な例

この例は、Adapter 設計パターンの構造を示しており、次の質問に答えることに重点を置いています。

  • これはどのようなクラスで構成されていますか?
  • これらのクラスはどのような役割を果たしますか?
  • パターン内の要素は互いにどのように関係しているのでしょうか?

このパターンの構造を理解すると、次の実際の PHP アプリケーションのケースをより簡単に理解できるようになります。

index.php: 概念例

<?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: 実行結果

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.

推奨調査:《PHP ビデオ チュートリアル>>

以上がPHP アダプター パターンの詳細な説明 (コード例付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.imで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。