php-design-patterns
A collection of design patterns written in PHP
This website collects cookies to deliver better user experience
SignUpService
contém apenas o destinatário e o conteúdo, enquanto ThirdPartyEmailClient
espera parâmetros de configuração.class ThirdPartyEmailClient
{
public function __construct(
private string $apiKey,
private string $region,
) {
}
public function sendEmail(
string $recipient,
string $content,
): void {
echo sprintf("Using apiKey %s and region %s", $this->apiKey, $this->region);
echo sprintf("Sending email to %s and content %s", $recipient, $content);
}
}
ThirdPartyEmailClient
está pedindo por uma apiKey
e region
, vamos satisfazer seus pedidos. Nós podemos simplesmente injetar os dois parâmetros na classe SignUpService
, ou mesmo colocando eles diretamente no código (hardcoding). Não seria um problema até você precisar depois enviar um email após o usuário atualizar o seu perfil, implementado em outra classe chamada ProfileService
.SignUpService
. Bom trabalho!apiKey
também está exposta em todos os lugares. Como resolver esse problema?Adapter
. Ele serve para integrar classes que tem interfaces incompatíveis. O primeiro passo é criar a interface esperada pelo cliente:interface EmailSenderAdapter
{
public function sendEmail(string $recipient, string $content): void;
}
ThirdPartyEmailClient
numa classe que implementa a interface anterior:final class ThirdPartyEmailSenderAdapter implements EmailSenderAdapter
{
public function __construct(private ThirdPartyEmailClient $emailClient)
{
}
public function sendEmail(string $recipient, string $content): void
{
$this->emailClient->sendEmail($recipient, $content);
}
}
SignUpService
agora está feliz porque tem um amigo que entende sua linguagem.public function testThirdPartyEmailSenderAdapterAdapterUsesCorrectClient(): void
{
$emailClient = $this->createMock(ThirdPartyEmailClient::class);
$emailAdapter = new ThirdPartyEmailSenderAdapter($emailClient);
$emailClient->expects($this->once())
->method('sendEmail')
->with('[email protected]', 'I love design patterns');
$emailAdapter->sendEmail(
'[email protected]',
'I love design patterns');
}
EmailSenderAdapter
, e então a interface antiga pode ser trocada pela nova. Parabéns.