1、解释器模式
这个模式好像就是用来作一种非常简单的解释器?比如数学表达式??比如命令行???
2、策略模式
放个书中的图吧
首先,,
一个.jpg
然后可能问题要分文文本问题,和多媒体问题,都需要相同的标记策略
多个.jpg
嗯,一眼就看出这样不对了,所以,,
提取.jpg
书中的例子,,,那3个策略,不能放在问题的父类中吗??
我想,放在父类中的话,如果需要增加策略,又要改现成的代码了。
现在的话,要增加策略,只要实现一个Marker类的子类就可以了!!
总之要记住!!!尽量做到不要修改原来的东西!!
也就是开闭原则:对扩展开放,对修改关闭。
当发现某个模式,好像把东西变复杂了,心里就要默念,这都是为了扩展的时候,只需要添加一个类,而不是修改原来的类!
3、观察者模式
书中的例子:我们做了一个登录类,现在市场部要求在登录时,在日志中记录IP地址,好的,在登录方法中加入该功能。管理员为了安全,要求登录失败时,发一封邮件到管理员邮箱,好的,在登录方法中加入该功能。因为登录是很重要的,可能越来越多的部门,要求在登录时,记录或被通知一些关于登录的信息。。你的这个类方法就越来越臃肿了。
<?php
class Login
{
const LOGIN_USER_UNKNOWN = 1;
const LOGIN_WRONG_PASSWD = 2;
const LOGIN_ACCESS = 3;
private $status = [];
// 验证登录
public function handleLogin($user, $pass, $ip)
{
// 模拟各种登录情况
switch (mt_rand(1, 3)) {
case 3:
$this->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;
}
}
现在,把登录作为主体(被观察类),每当主体事件发生时(登录时),客户元素(观察者,即管理员、市场部等其他要在主体中做特殊事情的客户)都需要收到他们需要的通知。通过观察者模式,把各种观察者注册到主体中,而非硬编码在主体中。
<?php
interface Observable
{
public function attach(Observer $observer);
public function detach(Observer $observer);
public function notify();
}
class Login implements Observable
{
// 略......
private $observers;
public function __construct()
{
$this->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标准库里,已经有观察者模式的接口可供直接使用~~
网友评论