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.對象僅需要將自己的更新通知給其他對象而不需要知道其他對象的細節