任务
通过SMS消息向用户添加警报系统,并可以选择提供商。决断
我认为最好的解决方案是添加自己的组件。组件是具有明确定义的一组动作(合同)的程序块,可以解决通过各种驱动程序分配给它的任务。例如,内置的组件Cache
可以使用驱动程序:file
,memcached
或redis
。在构建组件时,我们将应用设计桥梁的原理,即与Laravel组件所基于的原理相同。因此,让我们开始吧。车手
正如其中一项假设所述:按照接口编程,而不是根据实现编程。我们将从它开始,但是在组件的上下文中,使用术语合同更为准确。合同本质上是一组用于描述组件功能的接口。interface SmsContract
{
public function send();
}
接下来,添加执行合同的驱动程序。我们在一个抽象类中取出一般逻辑。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();
}
我们将直接在每个驱动程序类中描述发送逻辑。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)
]);
}
}
组件管理
要选择和配置驱动程序,请添加从class SmsManager
继承的类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']
);
}
}
现在,只需在配置文件中指定必要的参数,该类SmsManager
将告诉我们的组件通过哪个驱动程序发送SMS消息。正面
要从应用程序中的任何位置访问组件的功能,请添加Facade。首先,创建外观类本身:use Illuminate\Support\Facades\Facade;
class Sms extends Facade
{
protected static function getFacadeAccessor()
{
return 'sms';
}
}
接下来,我们SmsManager
使用服务提供商将类与外观关联,并注册一个别名。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'];
}
}
最后,在配置文件(app/config/app.php
)中注册我们的服务提供商以及其他提供商。'providers' => [
...
App\Providers\SmsServiceProvider::class,
],
应用
为我们的组件创建外观时,并在配置文件中指定参数后,要发送SMS消息,只需添加以下代码:Sms::to($phone)->content('Beware! He`s not who he is')->send();
或者,如果您需要显式指定驱动程序:Sms::setDriver('sms_ru')->to($phone)->content('why don`t you answer me?')->send();
结论
我们的组件基于设计Bridge的原理构建,也就是说,实现和抽象是分开的,以便可以独立更改它们。我们可以通过class管理驱动程序SmsManager
,而应用程序代码本身保持不变。通过外观可以轻松访问组件的功能。这种组件设计方法在使用中提供了简单性和灵活性。参考文献
Laravel Socialite组件,用于通过各种社交网络进行身份验证