php设计模式之观察者模式(Observer)

观察者模式,就是在主任务之外的辅助任务,及不影响主任务,也可以随意增减辅助任务,方便需求修改,也是维持代码整洁易读的好方法。

登录是一个典型的例子,我们处理登录任务时,除了判断用户登录成功、失败的信息之外,还要记录用户登录失败的信息,登录日志处理,或者产品的特殊需求,某个用户登录发个邮件啥的

还有某个用户发了一条消息,给特别关注用户发提醒等等吧

如果这些都写在过程里,会影响代码执行,某一天你会发现代码很长了还在增长。那么观察者模式是一个解决这个问题的很好的工具。

下面我们自己写一个观察者模式,当然php系统提供管缠着模式的封装。

<?php

interface Observable{

    function attach(Observer $observer);

    function detach(Observer $observer);

    function notify();

}

class Login implements Observable{

    private $observers;

    const LOGIN_USER_UNKONWN = 1;

    const LOGIN_WRONG_PASS = 2;

    const LOGIN_ACCESS = 3;

    private $status = array();


    function __construct(){

        $this->observers= array();

    }

    function attach(Observer $observer){

        $this->observers[]=$observer;

    }

    function detach(Observer $observer)

    {

        $this->observers = array_udiff($this->observers,array($observer),

            function($a,$b){ if($a===$b){return false;}else{ return true;}});

    }

    function notify(){

        foreach($this->observers as $observer)

        {

            $observer->update($this);

        }

    }

    function handleLogin($user, $pass, $ip)

    {

        switch(rand(1,3)){

            case 1:

                $this->setStatus(self::LOGIN_ACCESS,$user,$ip);

                $ret = true;break;

            case 2:

                $this->setStatus(self::LOGIN_WRONG_PASS,$user,$ip);

                $ret = false;break;

            case 3:

                $this->setStatus(self::LOGIN_USER_UNKONWN,$user,$ip);

                $ret = false;break;

        }

        $this->notify();

        return $ret;

    }

    private function setStatus($status, $user,$ip){

        $this->status = array($status, $user,$ip);

    }

    function getStatus(){

        return $this->status;

    }

}

interface Observer{

    function update(Observable $observer);

}

abstract class LoginObserver implements Observer{

    private $login;

    function __construct(Login $login){

        $this->login = $login;

        $login->attach($this);

    }

    function update(Observable $observer){

        if($observer === $this->login)

        {

            $this->doUpdate($observer);

        }

    }

    abstract function doUpdate(Login $login);

}

class SecurityMoniter extends LoginObserver{

    function doUpdate(Login $login){

        $status = $login->getStatus();

        if($status[0] == Login::LOGIN_WRONG_PASS)

        {

        print __CLASS__.":\t send email to sysadmin\n";

        }

    }

}

class GeneralLogger extends LoginObserver{

    function doUpdate(Login $login)

    {

        $status = $login->getStatus();

        print __CLASS__.".\t add login data to log\n";

    }

}

class PartnerShipTool extends LoginObserver{

    function doUpdate(Login $login)

    {

        $status = $login->getStatus();

        print __CLASS__."\t set cookie if IP matches a list\n";

    }

}

$login = new Login();

$securityMoniter = new SecurityMoniter($login);

$generalLogger = new GeneralLogger($login);

$partnerShipTool = new PartnerShipTool($login);

$login->handleLogin("admin", "12345", "127.0.0.1");


运行结果:

SecurityMoniter: send email to sysadmin

GeneralLogger. add login data to log

PartnerShipTool set cookie if IP matches a list

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容