Ir ao conteúdo

Padrão de Projeto Proxy em PHP com exemplo

Com o Padrão de Projeto Proxy você consegue controlar o acesso a um objeto de modo a prover somente as funções permitidas a um determinado cliente.  Ou seja, ele encapsula um objeto que possui a mesma implementação de interface de um segundo objeto, chamado proxy, que controla o acesso ao primeiro. 

Diagrama de Classe do Padrão de Projeto Proxy
Diagrama de Classe do Padrão de Projeto Proxy

Veja no diagrama de classe e observe que esse pattern é basicamente uma classe que representa outra classe, neste caso o Objeto Real que terá o seu acesso controlado pelo Objeto Proxy. Observe também que da forma que este padrão foi pensado, você poderá criar mais de um proxy para um determinado RealSubject e criar uma espécie de encadeamento.

Certamente em algum momento você esbarrou em algum Proxy de internet. Como poderíamos representar essa implementação, por exemplo, de controle de conexão com a internet?

A estrutura de uso deste padrão neste exemplo de controle de conexão, o contrato do Subject fica sendo a ação de conexão a um determinado site. Ou seja, se o site estiver na lista de negados, disparará uma exceção. Caso contrário, aparecerá uma mensagem com o sucesso da conexão.

Exemplo Padrão de Projeto Proxy
Exemplo Padrão de Projeto Proxy
<?php

declare(strict_types=1);

namespace Growthdev\DesignPatterns\Structural\Proxy;

final class Site
{
    public readonly string $url;

    public function __construct(string $url)
    {
        $this->url = $url;
    }
}
<?php

declare(strict_types=1);

namespace Growthdev\DesignPatterns\Structural\Proxy;

interface Internet
{
    public function connectTo(Site $site): void;
}
<?php

declare(strict_types=1);

namespace Growthdev\DesignPatterns\Structural\Proxy;

class RealInternet implements Internet
{
    public function connectTo(Site $site): void
    {
        printf("Connected to %s", $site->url);
    }
}
<?php

declare(strict_types=1);

namespace Growthdev\DesignPatterns\Structural\Proxy;

use Exception;

final class ProxyInternet implements Internet
{
    private Internet $internet;
    private array $bannedSites = [
        'http://xxxvideos.com',
        'http://xtzsite.com',
        'http://redsite.com',
        'http://sitetube.com'
    ];

    public function __construct()
    {
        $this->internet = new RealInternet();
    }

    public function connectTo(Site $site): void
    {
        if (in_array($site->url, $this->bannedSites)) {
            throw new Exception('Access denied');
        }

        $this->internet->connectTo($site);
    }
}

Esse exemplo nos dá uma noção muito boa de como utilizar este Padrão de Projeto. Acho o seu uso bastante simples e intuitivo. Observe nos testes a seguir que a classe Proxy Internet se tornou uma espécie de invólucro, ou seja, efetuou um “envelopamento” da classe Real Internet. Por esse motivo, podemos dizer que essa é uma classe wrapper.

<?php

declare(strict_types=1);

namespace Growthdev\DesignPatterns\Tests\Structural\Proxy;

use Exception;
use Growthdev\DesignPatterns\Structural\Proxy\ProxyInternet;
use Growthdev\DesignPatterns\Structural\Proxy\Site;
use PHPUnit\Framework\TestCase;

final class ProxyTest extends TestCase
{
    public function testExpectAccessToTheSiteDenied(): void
    {
        $this->expectException(Exception::class);
        $this->expectExceptionMessage('Access denied');

        $internet = new ProxyInternet();
        $internet->connectTo(new Site('http://xxxvideos.com'));
    }

    public function testExpectAccessToTheSiteGranted(): void
    {
        $internet = new ProxyInternet();
        $internet->connectTo(new Site('https://growthdev.com.br'));

        $this->expectOutputString('Connected to https://growthdev.com.br');
    }
}

Esse padrão de projeto estrutural é largamente utilizado. Se você quiser aprender sobre os outros padrões do livro GOF, veja no artigo Resumo dos Padrões de Projetos. Além disso, todos os códigos dos exemplos estou disponibilizando no meu Github:

https://github.com/growthdev-repo/design-patterns

Espero que você esteja gostando desta série de artigos. Até o próximo!

Confiança Sempre!!!

Fontes:

Publicado emDesign PatternPadrões de ProjetosPHP

Seja o primeiro a comentar

Deixe um comentário

O seu endereço de e-mail não será publicado.