0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

※学習用メモ デザインパターン:Proxy編[PHP]

Posted at

Proxyパターンとはどういうものか

Proxyとは代理人という意味です。

Proxy(プロキシ、代理人)とは、大まかに言えば、別の物のインタフェースとして機能するクラスである。その「別の物」とは何でもよく、ネットワーク接続だったり、メモリ上の大きなオブジェクトだったり、複製がコスト高あるいは不可能な何らかのリソースなどである。(wikipediaより)

要約すると、処理全体に大きなリソースを要する場合、その一部の処理をProxy(代理人)がこなす、というものです。

登場するクラス

Subject:ProxyとRealSubjectを同一視するためのインターフェース
Proxy:RealSubjectの処理を一部代替するクラス。
 自身で処理できないものはRealSubjectに任せる。Proxyでは、本当にRealSubjectが必要となった際のみRealSubjectを生成する。
RealSubject:代理人であるProxyが処理できない際に処理を行うReal(本人)のクラス

Proxyパターンのメリット

・メリット
多くのリソースが必要となる処理が必要ない場合、代理人のクラスその部分以外の処理を任せることで処理を省力化できる

[参考]
https://ja.wikipedia.org/wiki/Proxy_%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3
https://qiita.com/i-tanaka730/items/47efbab5eccc2d36759f
https://tic40.hatenablog.com/entry/2017/06/21/080000
https://www.ritolab.com/entry/142

サンプルコード

仕様

・キャラクターの情報を表示します。
・キャラクターの画像の読み込みに時間を要するため、画像の表示の必要が無い場合は処理をProxy(代理人)のクラスにて行います。

ProxyとRealSubjectのインターフェース(Subject)

CharacterInfoInterface.php
/**
 * Subjectインターフェース
 */
interface CharacterInfoInterface
{
    public function getCharacterInfo();
    public function displayImage();
}

キャラクターのクラス

Character.class.php
/**
 * キャラクターのクラス
 */
class Character
{
    private $name = "";
    private $img = "";
    private $profession = "";

    public function __construct($name, $img, $profession)
    {
        $this->name = $name;
        $this->img = $img;
        $this->profession = $profession;
    }

    public function getName()
    {
        return $this->name;
    }

    public function getImg()
    {
        return $this->img;
    }

    public function getProfession()
    {
        return $this->profession;
    }
}

代理人として処理を行うクラス(Proxy)
ここでは画像表示以外の処理を代理で行います。
画像表示についてはRealSubjectに任せています。

CharacterInfoProxy.class.php
/**
 * キャラクター情報の代理人クラス
 */
class CharacterInfoProxy implements CharacterInfoInterface
{
    private $character = "";

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

    public function getCharacterInfo()
    {
        return "名前:" . $this->character->getName() . "\n" .
        "職業:" . $this->character->getProfession() . "\n";
    }

    public function displayImage()
    {
        $real = new RealCharacterInfo($this->character);
        return $real->displayImage();
    }
}

本人クラス(RealSubject)
ここでは画像表示処理に必要なリソースが大きい仕様のため、sleepメソッドを用いて疑似的に重くしています。
また、動作の流れが分かるよう都度出力を行っています。

RealCharacterInfo.class.php
/**
 * キャラクター情報の本人クラス
 */
class RealCharacterInfo implements CharacterInfoInterface
{
    private $character = "";

    public function __construct($character)
    {
        $this->character = $character;
        echo "====RealCharacterInfoを生成しました。====\n";
    }

    public function getCharacterInfo()
    {
        return "名前:" . $this->character->getName() . "\n" .
        "職業:" . $this->character->getProfession() . "\n";
    }

    public function displayImage()
    {
        echo "画像表示処理中...\n";
        for ($i = 0; $i < 2; $i++) {
            sleep(1);
            echo "*\n";
        }
        echo "完了\n";

        return $this->character->getImg();
    }
}

使ってみる

$character = new Character("影虎", "/AAA/kagetora.png", "将軍");
$characterInfoProxy = new CharacterInfoProxy($character);

print_r($characterInfoProxy->getCharacterInfo());
print_r($characterInfoProxy->displayImage());

/*結果
名前:影虎
職業:将軍
====RealCharacterInfoを生成しました。====
画像表示処理中...
*
*
完了
/AAA/kagetora.png
*/

まとめ

・Proxyパターンは、処理に大きなリソースを要する場合、その一部の処理をProxy(代理人)がこなすことで処理を省力化できます。
・このパターンは今までのパターンとはやや視点が異なり、処理のリソースなどに目を向けるものでありましたが、今まであまり処理のリソース等について考慮できていなかった為今後のプログラム作成・設計の際にも意識しておこうと感じました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?