Tarefa
Adicione um sistema de alerta aos usuários por meio de mensagens SMS com a opção de escolher um provedor.Decisão
A melhor solução, na minha opinião, é adicionar seu próprio componente.Um componente é um bloco de programa com um conjunto claramente definido de ações (contrato) que pode resolver as tarefas atribuídas a ele por meio de vários drivers. Por exemplo, o componente interno Cache
pode usar o controlador: file
, memcached
ou redis
.Ao construir nosso componente, aplicaremos o princípio de design de Bridge, o mesmo princípio no qual os componentes do Laravel são construídos.Então vamos começar.Drivers
Como diz um dos postulados: programa de acordo com a interface e não com a implementação.Vamos começar com isso, mas no contexto do componente é mais preciso usar o termo contrato. Um contrato é essencialmente um conjunto de interfaces para descrever a funcionalidade de um componente.interface SmsContract
{
public function send();
}
Em seguida, adicione os drivers que executam o contrato. Retiramos a lógica geral em uma classe abstrata.abstract class Driver implements SmsContract
{
protected $message;
protected $recipient;
public function to($phoneNumber)
{
$this->recipient = $phoneNumber;
}
public function content($message)
{
$this->message = $message;
}
abstract public function send();
}
E descreveremos diretamente a lógica de envio em cada classe de driver.class SmsRuDriver extends Driver
{
protected $client;
protected $from;
public function __construct(SmsRuClient $smsRuClient, $from)
{
$this->client = $smsRuClient;
$this->from = $from;
}
public function send()
{
return $this->client->sendSms([
'type' => 'text',
'from' => $this->from,
'to' => $this->recipient,
'text' => trim($this->message)
]);
}
}
class SmartSenderDriver extends Driver
{
protected $client;
protected $from;
public function __construct(SmartSenderClient $smartSenderClient, $from)
{
$this->client = $smartSenderClient;
$this->from = $from;
}
public function send()
{
return $this->client->message()->send([
'type' => 'text',
'from' => $this->from,
'to' => $this->recipient,
'text' => trim($this->message)
]);
}
}
Gerenciamento de componentes
Para selecionar e configurar drivers, adicione uma classe SmsManager
herdada da classe Manager
.use Illuminate\Support\Manager;
class SmsManager extends Manager
{
public function setDriver($name = null)
{
return $this->driver($name);
}
public function createSmsRuDriver(): SmsContract
{
return new SmsRuDriver(
$this->createSmsRuClient(),
$this->app['config']['sms.sms_ru.from']
);
}
public function createSmartSenderDriver(): SmsContract
{
return new SmartSenderDriver(
$this->createSmartSenderClient(),
$this->app['config']['sms.smart_sender.from']
);
}
public function getDefaultDriver()
{
return $this->app['config']['sms.default'];
}
protected function createSmsRuClient()
{
return new SmsRuClient(
$this->app['config']['sms.sms_ru.key'],
$this->app['config']['sms.sms_ru.secret']
);
}
protected function createSmartSenderClient()
{
return new SmartSenderClient(
$this->app['config']['sms.smart_sender.key'],
$this->app['config']['sms.smart_sender.secret']
);
}
}
Agora basta especificar os parâmetros necessários no arquivo de configuração e a classe informará SmsManager
nosso componente através de qual driver enviar mensagens SMS.Fachada
Para acessar a funcionalidade do componente de qualquer lugar do aplicativo, adicione uma fachada .Primeiro, crie a própria classe de fachada:use Illuminate\Support\Facades\Facade;
class Sms extends Facade
{
protected static function getFacadeAccessor()
{
return 'sms';
}
}
Em seguida, associamos a classe SmsManager
à fachada usando o provedor de serviços e registramos um alias.class SmsServiceProvider extends ServiceProvider
{
protected $defer = true;
public function register()
{
$this->app->singleton('sms', function ($app) {
return new SmsManager($app);
});
}
public function provides()
{
return ['sms'];
}
}
Por fim, registre nosso provedor de serviços junto com os outros provedores no arquivo de configuração ( app/config/app.php
).'providers' => [
...
App\Providers\SmsServiceProvider::class,
],
Inscrição
Quando uma fachada é criada para o nosso componente e os parâmetros são especificados no arquivo de configuração, para enviar uma mensagem SMS, basta adicionar o seguinte código:Sms::to($phone)->content('Beware! He`s not who he is')->send();
Ou, se você precisar especificar explicitamente o driver:Sms::setDriver('sms_ru')->to($phone)->content('why don`t you answer me?')->send();
Conclusão
Nosso componente é construído com base no princípio de projetar uma ponte, isto é, implementação e abstração são separadas de forma que possam ser alteradas independentemente. Podemos gerenciar drivers através da classe SmsManager
, enquanto o próprio código do aplicativo permanece inalterado.A fachada fornece acesso fácil à funcionalidade do nosso componente.Essa abordagem ao design de componentes fornece simplicidade e flexibilidade em seu uso.Referências
Componente Socialite do Laravel para autenticação através de várias redes sociais