算是在實做過程中發現一些問題,然後重構這個強力工具!

我知道我目前碰到一個危險的境界,由於這個插件的類別非常強力,我經常拿他來替代繼承,我知道有點過頭了,但它真的很好用!
~我是說你可以維持一個物件變數,然後把需要功能一直掛入(只要你繼承這個抽象的插件類別,寫出你需要的功能)~

這幾天一直為了unset前後記憶用量沒有改變的問題無法釋懷,後來問了 kiang,他表示那是 Zend 引擎還沒到記憶體回收的週期,所以不會釋放~
這個類別的 __更新() 方法有一個地方我一直無法瞭解為何會有這個效果,知道的網友請開示吧~

另外一提,ADODB Lite 目前仍然是記憶用量最小的 DB Layer ,我自己寫的這個 DB Layer 跟它比較,兩邊都不掛任何多餘的模組,硬是比它大了約 50 K...
我該檢討了~


<?php
abstract class Zyme_Class_Plugin{
    private $_插件 = array();
    private $_方法 = array();
    private $_反映 = array();

    function __construct($宿主 = null){
        static $類別 = __CLASS__;
        if ($宿主 instanceof $類別) {
            $this->__插件($宿主);
        }       
    }
   
    final function __call($方法, $參數){
        return call_user_func_array($this->_方法[$方法], $參數);
    }

//    清除插件方法
    final protected function __清除(){
        $this->_插件 = array();
        $this->_方法 = array();
        $this->_反映 = array();
    }   

//    測試某個插件是否已安裝
    final protected function __已裝($類別){
        return isset($this->_插件[$類別]);
    }
   
//    將插件的方法加入$this的方法中
    final protected function __插件(Zyme_Class_Plugin $插件){
        $類別 = get_class($插件);
        if (false == $this->__已裝($類別)){
            $this->_插件[$類別] = $插件;
            $this->_方法 = $插件->__反映() + $this->_方法;
        }
    }

//    取得插件的可呼叫方法列表
    final function __方法(){
        return $this->_方法;
    }

//    取得插件本身的方法列表(除了方法名稱開頭是'__'的方法,例如一些魔術方法,或是方法本身屬於私有方法)
    final private function __反映(){
        $輸出 = &$this->_反映;
        if (false == empty($輸出)) {
            return $輸出;
        }
        $反映 = new ReflectionObject($this);
        $方法 = $反映->getMethods();
        foreach ($方法 as $項目){
            $名稱 = $項目->getName();
            if (0 !== strpos($名稱, '__') && false == $項目->isPrivate()) {
                $輸出[$名稱] = array($this, $名稱);
            }
        }
        return $輸出; 
    }

//    匯入插件的可呼叫方法表
    final function __匯入(Zyme_Class_Plugin $宿主){
        $this->_方法 = $宿主->__方法() + $this->_方法;
    }

//    更新所有插件的方法,通常在載入所有插件後調用
    final protected function __更新(){
        foreach ($this->_插件 as $插件){           
            $插件->_方法 = $this->_方法 + $插件->_方法;    //    照理說,這行應該會出現錯誤(存取私有成員),但不知為何可以執行
//            $插件->__匯入($this);    //    萬一未來版本上面那行無法執行時,可以改用這行
        }
    }
   
}

?>


arrow
arrow
    全站熱搜

    HACGIS 發表在 痞客邦 留言(4) 人氣()