class Cart { private $_items private $_listeners; public function __construct() { $this->_items = array(); $this->_listeners = array(); } public function add($cd) { $this->_items[$cd] = (isset($this->_items[$cd]))? ++$this->_items[$cd] : 1; $this->notify(); } public function remove($cd) { $this->_items[$cd] = (isset($this->_items[$cd]))? --$this->_items[$cd] : 0; if($this->_items[$cd] <= 0){ unset($this->_items[$cd]); } $this->notify(); } public function get() { return $this->_items; } public function has($cd) { return array_key_exists($cd, $this->_items); } public function notify() { foreach($this->_listeners as $listener){ $listener->update($this); } } public function addListener(CartListener $listener) { $this->_listeners[get_class($listener)] = $listener; } }
Listener.php
以下のようにインターフェースを定義する。
interface Listener { public function update(Cart $cart); }
以下のようにListenerを実装する。
PresentListener
class PresentListener implements Listener { const PRESENT_TARGET = '30:cookie'; const PRESENT_ITEM = '99:present'; public function __construct() { } public function update(Cart $cart) { if($cart->hasItem(self::PRESENT_TARGET) && !$cart->hasItem(self::PRESENT_ITEM)){ $cart->add(self::PRESENT_ITEM); } if(!$cart->hasItem(self::PRESENT_TARGET) && $cart->hasItem(self::PRESENT_ITEM)){ $cart->remove(self::PRESENT_ITEM); } } }
LoginListener
class LoginListener implements Listener { public function __construct() { } public function update(Cart $cart) { var_dump($cart->get()); } }