简单记录设计模式03(解释、策略、观察者模式)

1、解释器模式

这个模式好像就是用来作一种非常简单的解释器?比如数学表达式??比如命令行???

2、策略模式

放个书中的图吧
首先,,


简单记录设计模式03(解释、策略、观察者模式)_第1张图片
一个.jpg

然后可能问题要分文文本问题,和多媒体问题,都需要相同的标记策略


简单记录设计模式03(解释、策略、观察者模式)_第2张图片
多个.jpg

嗯,一眼就看出这样不对了,所以,,
简单记录设计模式03(解释、策略、观察者模式)_第3张图片
提取.jpg

书中的例子,,,那3个策略,不能放在问题的父类中吗??

我想,放在父类中的话,如果需要增加策略,又要改现成的代码了。
现在的话,要增加策略,只要实现一个Marker类的子类就可以了!!
总之要记住!!!尽量做到不要修改原来的东西!!
也就是开闭原则:对扩展开放,对修改关闭。
当发现某个模式,好像把东西变复杂了,心里就要默念,这都是为了扩展的时候,只需要添加一个类,而不是修改原来的类!

3、观察者模式

书中的例子:我们做了一个登录类,现在市场部要求在登录时,在日志中记录IP地址,好的,在登录方法中加入该功能。管理员为了安全,要求登录失败时,发一封邮件到管理员邮箱,好的,在登录方法中加入该功能。因为登录是很重要的,可能越来越多的部门,要求在登录时,记录或被通知一些关于登录的信息。。你的这个类方法就越来越臃肿了。

setStatus(self::LOGIN_ACCESS, $user, $ip);
                $ret = true;
                break;
            case 2:
                $this->setStatus(self::LOGIN_WRONG_PASSWD, $user, $ip);
                $ret = false;
                break;
            case 1:
                $this->setStatus(self::LOGIN_USER_UNKNOWN, $user, $ip);
                $ret = false;
                break;
        }
        // 市场部要求记录IP到日志中
        // 记录日志~~~

        // 管理员为了安全起见,希望登录失败时,收到一封邮件
        if (!$ret) {
            // 发送邮件给管理员
        }

        // 各种功能被插在这里
        return $ret;
    }

    private function setStatus($status, $user, $ip)
    {
        $this->status = [$status, $user, $ip];
    }

    public function getStatus()
    {
        return $this->status;
    }
}

现在,把登录作为主体(被观察类),每当主体事件发生时(登录时),客户元素(观察者,即管理员、市场部等其他要在主体中做特殊事情的客户)都需要收到他们需要的通知。通过观察者模式,把各种观察者注册到主体中,而非硬编码在主体中。

observers = [];
    }

    // 注册观察者
    public function attach(Observer $observer)
    {
        $this->observers[] = $observer;
    }

    // 去掉观察者
    public function detach(Observer $observer)
    {
        $new_observers = [];
        foreach ($this->observers as $obs) {
            if ($obs !== $observer) {
                $new_observers[] = $obs;
            }
        }
        $this->observers = $new_observers;
    }

    // 通知各个已注册的观察者
    public function notify()
    {
        foreach ($this->observers as $obs) {
            // 调用观察者自己特有的update方法,来获取他们需要的数据
            $obs->update($this);
        }
    }

    // 验证登录
    public function handleLogin($user, $pass, $ip)
    {
        // 模拟各种登录情况
        // 略......

        $this->notify();

        return $ret;
    }

    // [sg]etStatus略......
}

interface Observer
{
    function update(Observable $observable);
}

class SecurityMonitor implements Observer
{
    function update(Observable $observable)
    {
        $status = $observable->getStatus();
        if ($status[0] == Login::LOGIN_WRONG_PASSWD) {
            echo  __CLASS__ . ":\tsending email to sysadmin\n";
        }
    }
}

$login = new Login();
$login->attach(new SecurityMonitor());
$login->handleLogin('largezhou', '111', '127.0.0.1');

就这样,客户使用时,想要在登录时做点什么,就只需要自己实现一个Observer接口,并注册到Login中~~
书中的例子最后改进了一下,并且PHP标准库里,已经有观察者模式的接口可供直接使用~~

你可能感兴趣的:(简单记录设计模式03(解释、策略、观察者模式))