观察者模式主要用于解耦
1 没有观察者模式
class order { public function addOrder() { // 发短信 Message::update(); //发邮件 Email::update(); //记日志 Log::update(); } } $order = new order(); $order->addOrder();
2 观察者模式
2.1 被观察者 order
//被观察者 interface Observable { //添加观察者实例 function add(); //删除观察者实例 function del(); //通知观察者 function notify(); } //订单类继承被观察者接口 class order implements Observable { private $instance = array(); //添加观察者实例 function add(observe $observe) { // TODO: Implement add() method. $key = array_search($observe,$this->instance); if ($key === false){ $this->instance[] = $observe; } } //删除观察者实例 function del(observe $observe) { // TODO: Implement del() method. $key = array_search($observe,$this->instance); if ($key !== false){ unset($this->instance[$key]); } } //通知观察者实例 function notify() { // TODO: Implement notify() method. foreach ($this->instance as $key => $val){ //调用实例化对象的update方法 $val->update(); } } }
2.2 观察者 Email 、Message
/** * Interface observe * 定义一个观察者 */ interface observe() { //每个实例化对象都有update方法 function update(); } class Email implements observe { function update() { echo "订单修改了,发送邮件"; } } class Message implements observe { function update() { echo "订单修改了,发送短信"; } }
2.3 客户端调用
$order = new order(); $order->add(new Email()); $order->add(new Message()); $order->del(new Email()); $order->notify();
3 Laravel的事件机制
3.1 执行命令
php artisan make:event EventTest
php artisan make:listener EventTestListener
3.2 生成文件
\app\Listeners\EventTestListener.php
<?php namespace App\Listeners; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Queue\ShouldQueue; class EventTestListener { /** * Create the event listener. * * @return void */ public function __construct() { // } /** * Handle the event. * * @param object $event * @return void */ public function handle($event) { // echo "我是监听者/观察者 EventTestListener "; } }
\app\Events\EventTest.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; class EventTest { use Dispatchable, InteractsWithSockets, SerializesModels; /** * Create a new event instance. * * @return void */ public function __construct() { // } /** * Get the channels the event should broadcast on. * * @return \Illuminate\Broadcasting\Channel|array */ public function broadcastOn() { //return new PrivateChannel('channel-name'); } }
\routes\web.php
use App\Events\EventTest;
Route::get('/', function () { event(new EventTest()); });