Home > PHP编程 > PHP设计模式之观察者模式

PHP设计模式之观察者模式

先抛出一个问题,你的网站有一个新用户注册,假设你需要给用户发送一条站内信,一封电子邮件,给用户分配一个宠物。

那么假定程序需要4个类,分别是用户类(User),电子邮件类(Email),站内信息类(Message),宠物类(Pet)。

那么要解决上面的问题,我们可以直接在 用户对象中用户注册成功后面计入其他3个对象相应的处理方法。这样目的达到了,是否合理呢?

试想,现在用户类需要改动,有可能就会导致注册成功后的动作不能正常启动,或者我改动了其他3个类,我就必须回到User类中寻找到相应的代码进行修改。这样会造成很多不必要的麻烦,如果是团队协作,那就真是头疼了。

在OOP编程中,我们一直在说一个东西就是避免组件之间紧密耦合。上面给出的解决办法就违反了这一原则。观察者模式提供了避免组件之间紧密耦合的一种方法。

用观察者来分析以上问题:

User一个被观察的对象;
Email,Message,Pet是观察者;
首先观察者需要注册为User的观察者。
一当被观察者有相应的动作,观察者就会作出相应的反映。

代码清单:

//先定义一个用户注册观察者接口
interface IObserver{
    public function onChanged();
}

//同上我们需要定义一个被观察者抽象类
abstract class Observable{
    //观察者集合
    private $_observers;

    public function addObserver($observer)
    {
        $this->_observers=[] = $observer;
    }

    //通知各个观察者
    public function notify();
}

//用户类
class User extends Observable{
    public function register()
    {
        //注册过程省略,这里假定注册成功返回用户ID号($uid);
        if($uid) $this->notify($uid);
    }

    public function notify($uid)
    {
        foreach ($this->_observers as $os) {
            $os->onChanged($uid);
        }
    }

    //....
}

//邮件类
class Email implements IObserver{

    //其余代码省略

    public function onChanged()
    {
        $uid = func_get_arg(1);
        //根据$uid取得此函数需要的变量$email,$username
        //具体代码省略
        $this->setEmail($email);
        $this->setContent("{$username},欢迎您注册本站!");
        $this->send();
    }
}

//宠物类
class Pet implements IObserver{

    //其余代码省略

    public function onChanged()
    {
        $uid = func_get_arg(1);
        $this->setPet($uid);
    }
}

//信息类
class Message implements IObserver{

    //其余代码省略

    public function onChanged()
    {
        $uid = func_get_arg(1);
        $this->sendMsg($uid, '欢迎注册本站!');
    }
}

//驱动类
class Drive{
    public function main()
    {
        $user = new User;
        //注册观察者
        $user->addObserver( new Email() );
        $user->addObserver( new Message() );
        $user->addObserver( new Pet() );

        $user->register();
    }
}

$drive = new Drive;
$drive->main();

POSTED ON 2010年06月14日,

发表您的看法

Trackbacks:0

Listed below are links to weblogs that reference
PHP设计模式之观察者模式 from andery's blog
TOP

Videos, Slideshows and Podcasts by Cincopa Wordpress Plugin