观察者模式主要用于解耦
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 生成文件
appListenersEventTestListener.php
<?php namespace AppListeners; use IlluminateQueueInteractsWithQueue; use IlluminateContractsQueueShouldQueue; 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 "; } }
appEventsEventTest.php
<?php namespace AppEvents; use IlluminateBroadcastingChannel; use IlluminateQueueSerializesModels; use IlluminateBroadcastingPrivateChannel; use IlluminateBroadcastingPresenceChannel; use IlluminateFoundationEventsDispatchable; use IlluminateBroadcastingInteractsWithSockets; use IlluminateContractsBroadcastingShouldBroadcast; 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 IlluminateBroadcastingChannel|array */ public function broadcastOn() { //return new PrivateChannel('channel-name'); } }
outesweb.php
use AppEventsEventTest;
Route::get('/', function () { event(new EventTest()); });