php有多少种设计模式?
这是不是一个灵魂拷问捏
php有五种设计模式,相信各位大佬都是懂的
有策略模式、工厂模式、单例模式、注册模式、适配器模式、观察者模式
该篇要讲的是观察者模式(Observer)
概念:
当一个对象状态发生变化时,依赖它的对象会监控到该变化,做出事件发生后要执行的逻辑,属于被动行为。观察者模式实现了低耦合,非侵入式的通知与更新机制
优点:
1.观察者模式在被观察者和观察者之间建立一个抽象的耦合。被观察者角色所知道的只是一个具体观察者列表,每一个具体观察者都符合一个抽象观察者的接口。被观察者并不认识任何一个具体观察者,它只知道它们都有一个共同的接口
2.由于被观察者和观察者没有紧密地耦合在一起,因此它们可以属于不同的抽象化层次。如果被观察者和观察者都被扔到一起,那么这个对象必然跨越抽象化和具体化层次
3.观察者模式支持广播通讯。被观察者会向所有的登记过的观察者发出通知
laravel的观察者应该是怎样呢?
添加监听
laravel在 \app\Providers\EventServiceProvider.php 文件夹下已经定义好事件监听,我们首先需要把自己的监听者定义上去
// 新增事件
'App\Events\EmailLogin' => [
// 发送邮箱验证码
'App\Listeners\SendEmail',
],
如下:
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Event;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
'App\Events\Event' => [
'App\Listeners\EventListener',
],
// 新增事件
'App\Events\EmailLogin' => [
// 发送邮箱验证码
'App\Listeners\SendEmail',
],
];
/**
* Register any events for your application.
*
* @return void
*/
public function boot()
{
parent::boot();
//
}
}
DOS
php artisan event:generate
*创建监听者文件
修改文件
EmailLogin.php
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Admins;
class EmailLogin
{
use Dispatchable, InteractsWithSockets, SerializesModels;
protected $email_binding;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct($email_binding)
{
$this->email_binding = $email_binding;
}
/**
* Get the channels the event should broadcast on.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('channel-name');
}
}
SendEmail.php
<?php
namespace App\Listeners;
use App\Events\EmailLogin;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Jobs\SendEmail as send;
class SendEmail
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* @param EmailLogin $event
* @return void
*/
public function handle(EmailLogin $event)
{
$email = Send::dispatch($event);
}
}
路由(event() 触发监听者事件)
Route::any('/login', function () {
$email = "*******@qq.com";
$email_binding = (object) ['email' => $email];
event(new EmailLogin($email_binding)); //触发监听者事件
});
测试
邮件事件
Jobs\SendEmail
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Mail;
class SendEmail implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $mail_binding;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct($mail_binding)
{
$this->mail_binding = $mail_binding;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
$mail_binding = $this->mail_binding;
Mail::send('send',$mail_binding, function ($message) use ($mail_binding) {
$message->to($mail_binding->email)->subject('登录验证');
});
}
}
观察者模式的应用场景:
1.对一个对象状态的更新,需要其他对象同步更新,而且其他对象的数量动态可变
2.对象仅需要将自己的更新通知给其他对象而不需要知道其他对象的细节