+ -
当前位置:首页 → 问答吧 → 用PHP实现装饰或包装模式

用PHP实现装饰或包装模式

时间:2008-03-07

来源:互联网

老王的BLOG上有篇帖子”PHP实现透明化事务处理“,谈到了装饰模式(包装模式),感觉受到很大启发,

经过一番胡思乱想后,最终结合PHP的特点,用以下方式实现可能最好,这个设计完全是独自想到的,没参考任何先人的思想,难免有不足之处,欢迎指正!

<?php
class FooAction {
    public function execute() {
         echo "<br />\r\n";
         echo "FooAction::execute()<br />\r\n";
         echo "<br />\r\n";
    }
}

//转帖请注明作者trooman

abstract class WrapperBehavior {
        abstract public function before();
        abstract public function after();
      
        public function getName() {
                return get_class($this);
        }
}

class Authorization extends WrapperBehavior {
        public function before() {
                echo "Authorization begin<br />\r\n";
        }
      
        public function after() {
                echo "Authorization end<br />\r\n";
        }
}

class Transaction extends WrapperBehavior {
        public function before() {
                 echo "Transaction begin<br />\r\n";
        }
      
        public function after() {
                echo "Transaction end<br />\r\n";
        }
}

class Wrapper {
        protected $_srcObj = null;
        protected $_wrapperBehaviors = array();
      
        public function __construct($obj) {
                $this->_srcObj = $obj;
        }
      
        public function add($srcMethod, $wrapperBehavior) {
                $this->_wrapperBehaviors[$srcMethod][$wrapperBehavior->getName()] = $wrapperBehavior;
        }
      
        public function __call($method, $args) {
                if (! method_exists($this->_srcObj, $method)) {
                        throw new Exception("The method {$method} not exists");
                }
               
                //before
                foreach (array_reverse($this->_wrapperBehaviors[$method]) as $behavior) {
                        $behavior->before();
                }
               
                call_user_func_array(array(&$this->_srcObj, $method), $args); //用反射可能更好
               
                //end
                foreach ($this->_wrapperBehaviors[$method] as $behavior) {
                        $behavior->after();
                }
        }
}


$action = new FooAction();
$wrapper = new Wrapper($action);
$wrapper->add('execute', new Transaction());
$wrapper->add('execute', new Authorization());
$wrapper->execute();

作者: trooman   发布时间: 2008-03-07

作者: luzhou   发布时间: 2008-03-07

作者: strongability   发布时间: 2008-03-08