PHP China | 中国开源之路 's Archiver

PHPChina 发表于 2006-3-4 23:45

->Observer Pattern(映象模式)

->映象模式(Observer Pattern)
PHP的应用,最多的就是处理数据。在多数情况下,改变一个模块的数据会影响到应用里面很多其它的方面。例如,一个电子商务的网站需要罗列许多商品的价格,其中不同币种的汇率就会对整个站点的商品的价格起到影响作用。假设一个商品的价格使用一个基础类产生的PHP实例来体现的。而现金的汇率本身是从另外的数据源产生,并不包含在商品本身的对象中。同时,每个的商品的对象都有一个display()的方式函数来把价格等相关元素输出到HTML里面。
   那么映象模式(Observer Pattern)可以实现PHP的对象注册到一些特定的事件或数据,当这些特定的事件或者数据改变的时候,对象的相关元素就自动被改变了。这样的话,你就可以让产品的对象映象到现金汇率了,那么当你发现现金汇率改变的时候,你就可以在输出到HTML前让PHP自动更改相关对象实例的内容。这样做的目的是保持数据能够得到及时的更新。
   通常来讲,映象设计模式是通过一个叫Observer的接口来实现的,这个接口在声明类的时候就需要声明。例如:
   interface Observer{
       function notify($obj);
   }
   一个对象需要被映象通常需要具备一个注册(register)方式函数能够提供注册。请看下面的例子:
   代码:observer_pattern.php

PHPChina 发表于 2006-3-4 23:45

[php]
<?php
interface Observer{
        function notify($obj);
}

class ExchangeRate {
        static private $instance = null;
        private $observer = array();
        private $exchange_rate;
       
        private function ExchangeRate()
        {
               
        }
       
        static public function getInstance()
        {
                if (self::$instance == null) {
                        self::$instance = new ExchangeRate();
                }
                return self::$instance;
        }
        public function getExchangeRate()
        {
                return $this->exchange_rate;
        }
        public function setExchangeRate($new_rate)
        {
                $this->exchange_rate = $new_rate;
                $this->notifyObservers();
        }
        public function registerObserver($obj)
        {
                $this->observers[] = $obj;
        }
       
        function notifyObservers()
        {
                foreach ($this->observers as $obj){
                        $obj->notify($this);
                }
        }
}


class ProductItem implements Observer {
        public function __construct()
        {
                ExchangeRate::getInstance()->registerObserver($this);
        }
    public function notify($obj)
    {
            if ($obj instanceof ExchangeRate ) {
                    //update exchange rate date
                    print "Received update!\n";
            }
    }
}


$product1 = new ProductItem();
$product2 = new ProductItem();

ExchangeRate::getInstance()->setExchangeRate(4.5);

?>
[/php]

PHPChina 发表于 2006-3-4 23:45

虽然这个例子不是很完整,但是最后一行执行的(setExchangeRate()方式函数),两个不同的对象$product1和$product2都通过他们的notify()方式函数更新了数据,使用了最新的现金汇率。
   这个设计模式还可以在很多的场合下面使用:尤其在Web开发的时候,它可以用在一个大的框架对象。这个框架对象的数据都会自动地被其它的PHP数据影响到,比如cookies,GET和POST等等。

zhiin 发表于 2006-3-8 16:03

wenfeng2 发表于 2008-6-22 10:07

這個就是傳說中的觀察者模式吧~~:lol:

页: [1]

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.