首頁 >後端開發 >php教程 >使用觀察者模式處理異常訊息

使用觀察者模式處理異常訊息

WBOY
WBOY原創
2016-07-30 13:31:38961瀏覽

  異常訊息的捕捉對程式測試有著重要的意義,這裡結合觀察者模式,探索如何處理異常訊息。

  關於觀察者模式,如果還沒接觸過的話,博客園有很多優秀的博友做了詳細的 解釋。筆者覺得,所謂觀察者模式,必須有兩個重要組成部分:一個主題對象,多個觀察者。使用的時候,我們可以將觀察者像插頭一樣插到主題物件這個插座上,利用主題物件完成對應功能。

  既然觀察者要作為插頭,必須要有一個統一的口徑才能插到相同的插座上,因而先定義一個接口,Exception_Observer.php:

<?<span>php 
</span><span>/*</span><span>*
 * 定义的规范 
 </span><span>*/</span><span>interface</span><span> Exception_Observer{
    </span><span>public</span><span>function</span> update(Observer_Exception <span>$e</span><span>);
}
 
 </span>?>

  相對於眾多觀察者,我們應該關注唯一觀察者的主題對象,Observer_Exception.php:

<?<span>php
</span><span>class</span> Observer_exception <span>extends</span><span>Exception</span><span>{
    </span><span>public</span><span>static</span><span>$_observers</span>=<span>array</span><span>();
    </span><span>public</span><span>static</span><span>function</span> attach(Exception_Observer <span>$observer</span><span>){
        self</span>::<span>$_observers</span>[]=<span>$observer</span><span>;
    } 
    </span><span>public</span><span>function</span> __construct(<span>$message</span>=<span>null</span>,<span>$code</span>=0<span>){
        parent</span>::__construct(<span>$message</span>,<span>$code</span><span>);
        </span><span>$this</span>-><span>notify();
    }
    </span><span>public</span><span>function</span><span> notify(){
        </span><span>foreach</span> (self::<span>$_observers</span><span>as</span><span>$observer</span><span>) {
            </span><span>$observer</span>->update(<span>$this</span><span>);
        }
    }
}</span>

  我們可以清楚地看到,靜態變數$_observers用來放置插入的觀察者,notify()用來通知所有觀察者對象。

  這裡要注意 $observer->update($this); 裡面 $this  一個小問題: $_observers

 不是靜態變數可不可以? 這個問題我們後面回答。   定義兩個觀察者,原則上實現介面所定義的功能。   Email_Exception_Observer.php:

<span>class</span> Emailing_Exception_Observer <span>implements</span><span> Exception_Observer{
    </span><span>protected</span><span>$_email</span>="huanggbxjp@sohu.com"<span>;
    </span><span>function</span> __construct(<span>$email</span>=<span>null</span><span>)
    {
        </span><span>if</span> (<span>$email</span>!==<span>null</span>&&filter_var(<span>$email</span>,<span>FILTER_VALIDATE_EMAIL)) {
            </span><span>$this</span>->_email=<span>$email</span><span>;
        }
    }


    </span><span>public</span><span>function</span> update(Observer_Exception <span>$e</span><span>){
        </span><span>$message</span>="时间".<span>date</span>("Y-m-d H:i:s").<span>PHP_EOL</span><span>;
        </span><span>$message</span>.="信息".<span>$e</span>->getMessage().<span>PHP_EOL</span><span>;
        </span><span>$message</span>.="追踪信息".<span>$e</span>->getTraceAsString().<span>PHP_EOL</span><span>;
        </span><span>$message</span>.="文件".<span>$e</span>->getFile().<span>PHP_EOL</span><span>;
        </span><span>$message</span>.="行号".<span>$e</span>->getLine().<span>PHP_EOL</span><span>;
        </span><span>error_log</span>(<span>$message</span>,1,<span>$this</span>-><span>_email);
    }
}</span>

  Logging_Exception_Observer.php:

<?<span>php 
</span><span>class</span> Logging_Exception_Observer <span>implements</span><span> Exception_Observer
{
    </span><span>protected</span><span>$_filename</span>="F:/logException.log"<span>;
    </span><span>function</span> __construct(<span>$filename</span>=<span>null</span><span>)
    {
        </span><span>if</span> (<span>$filename</span>!==<span>null</span>&&<span>is_string</span>(<span>$filename</span><span>)) {
            </span><span>$thvis</span>->_filename=<span>$filename</span><span>;
        }
    }


    </span><span>public</span><span>function</span> update(Observer_Exception <span>$e</span><span>){
        </span><span>$message</span>="时间".<span>date</span>("Y-m-d H:i:s").<span>PHP_EOL</span><span>;
        </span><span>$message</span>.="信息".<span>$e</span>->getMessage().<span>PHP_EOL</span><span>;
        </span><span>$message</span>.="追踪信息".<span>$e</span>->getTraceAsString().<span>PHP_EOL</span><span>;
        </span><span>$message</span>.="文件".<span>$e</span>->getFile().<span>PHP_EOL</span><span>;
        </span><span>$message</span>.="行号".<span>$e</span>->getLine().<span>PHP_EOL</span><span>;
        </span><span>error_log</span>(<span>$message</span>,3,<span>$this</span>-><span>_filename);
    }
}</span>
<?<span>php 

</span><span>require</span> 'Exception_Observer.php'<span>;
</span><span>require</span> 'Observer_Exception.php'<span>;
</span><span>require</span> 'Logging_Exception_Observer.php'<span>;
</span><span>require</span> 'Emailing_Exception_Observer.php'<span>;

Observer_Exception</span>::attach(<span>new</span><span> Logging_Exception_Observer());

</span><span>class</span> MyException <span>extends</span><span> Observer_Exception{

    </span><span>public</span><span>function</span><span> test(){
        </span><span>echo</span> 'this is  a test'<span>;
    }
    </span><span>public</span><span>function</span><span> test1(){

        </span><span>echo</span> "我是自定义的方法处理这个异常"<span>;
    }

}

</span><span>try</span><span> {
    </span><span>throw</span><span>new</span> MyException("出现异常,记录一下"<span>);    
} </span><span>catch</span> (MyException <span>$e</span><span>) {
    </span><span>echo</span><span>$e</span>-><span>getMessage();
    </span><span>echo</span> "<ht/>"<span>;    
}
</span>?>

  本實例先載入觀察者,其後進行其他操作。回到上面提出的問題, 

$_observers

 可以不是靜態變數嗎?答案是不行。如果 

$_observers

 不是靜態變量,載入觀察者的行為對後續操作沒有影響。 static讓所有實例成員共用某個變數。即便類別繼承也同樣有效。有興趣的可以繼續探索下static的神奇作用。   本例顯示輸出與一般情況無異,但不同的是已在自訂的檔案下產生了對應的日誌。雖然最後實現的功能再簡單不過,很多人甚至可以用更少的程式碼更簡單的方法實現,但是,在實現更加複雜系統的情況下,觀察者模式給我們帶來很大方便。 以上就介紹了使用觀察者模式處理異常訊息,包括了方面的內容,希望對PHP教程有興趣的朋友有所幫助。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn