首頁  >  文章  >  php教程  >  Yii框架分析(五)-再談CComponent基礎類

Yii框架分析(五)-再談CComponent基礎類

黄舟
黄舟原創
2016-12-27 11:19:001115瀏覽

這篇文章可作為《Yii框架分析(二)——CComponent類剖析》的補充。

CComponent類別為YII框架的基於元件和事件驅動程式設計提供了基礎,YII框架中的大部分類別都將CComponent類別作為基底類別。 CComponent類別為它的子類別提供3個特性:

1、成員變數擴充
透過定義兩個成員函數(getXXX/setXXX)來定義一個成員變量,例如:
public function getText() {…}
public function setText {…}
這樣就相當於定義了一個$text成員變量,可以這樣調用

$a=new CComponent;
$a=$component->text; // 等价于$a=$component->getText();
$component->text='abc'; // 等价于$component->setText('abc');

CComponent是透過魔術方法__get和__set來實現「成員變數擴充」特性的,如果對類別本身不當存在的成員變數進行操作時,php會呼叫這個類別的__get和__set方法來處理。 CComponent利用這兩種魔術方法實現了「成員變數擴展」特性。下圖描述了一個CComponent的子類,它增加了active和sessionName兩個成員變量,該圖描述了對於這兩個成員變數的呼叫流程。

Yii框架分析(五)-再談CComponent基礎類

(註:關於魔術方法__get和__set的使用,可參考:PHP基礎之類和對象13——重載)

面向對象編程中直接定義一個成員變量就可以了,為什麼CComponent要透過定義2個函數來實作一個成員變數呢?一個主要得原因是需要對成員變數進行“延時載入”,一般情況下類別的成員變數是在建構函式或初始化函數進行統一賦值,但是在一次web請求的處理過程中不是每個成員變數都會被使用,例如App類別中定義了兩個成員變數:$cache和$db($cache是​​快取對象,$db是一個資料庫連結對象),這兩個對像在App類別初始化的時候創建,但是一個web網站的有些頁面,它內容可以透過快取獲取,那麼資料庫連結物件其實就不需要創建。如果將App定義為CComponent的子類,在App類別中定義兩個方法:getCache/getDb,這樣就可以做到第一次使用db成員變數的時候,才呼叫getDb函數來進行資料庫連結的初始化,從而實作延時載入-即在第一次使用時進行初始化。雖然延時加載會增加一次函數調用,但是可以減少不必要的成員變數的初始化(總體而言其實是提升了網站的訪問速度),而且可以使得我們的程式碼更加易於維護、易於擴展。
延時載入應該是「成員變數擴充」特性的最重要的用途,當然這個特性還會有其它用途,想一想,當你操作一個成員變數的時候,你其實是在呼叫getXXX和setXXX成員函數,你是在呼叫一段程式碼!

2、事件模型
事件模型就是設計模式中的「觀察者模式」:當物件的狀態發生了變化,那麼這個物件可以將該事件通知其它物件。
為了使用事件模型,需要實現這三個步驟:1、定義事件;2、註冊事件句柄;3、觸發事件。
CComponent的子類別透過定義一個以on打頭的成員函數來定義一個事件,例如:public function onClick(){…},接著透過呼叫attachEventHandler成員函式來註冊事件句柄(可以註冊多個事件句柄),最後透過呼叫raiseEvent來觸發事件。
CComponent類別使用一個私有的成員變數來保存事件以及處理該事件的所有句柄,該成員變數可以看作一個hash表,hash表的key是事件的名稱,hash表的value是事件處理函數鍊錶。

Yii框架分析(五)-再談CComponent基礎類

3、行為類別綁定
有兩種辦法可以對類別添加特性:1、直接修改這個類別的程式碼,加入一些成員函數和成員變數;2、派生,透過子類別來擴充。很明顯第二種方法比較容易維護、易擴展。如果需要對一個類別添加多個特性(多人在不同時期),那麼需要進行多級派生,這顯然加大了維護成本。
CComponent使用一種特殊的方式對類別資訊擴展—行為類別綁定。行為類別是一個CBehavior的子類,CComponent可以將一個或多個CBehavior類別的成員函數和成員變數加入到自己身上,並且在不需要的時候卸載某些CBehavior類別。以下是一個簡單的範例:
//計算器類別
class Calculator extends CBehavior
{
public function add($x, $y) { return $x + $y; }
public function sub($x, $y ) { return $x - $y; }
...
}
$comp = new CComponent();
//為我的類別添加計算器功能
$comp->attachbehavior('calculator', new Calculator( ));
$comp->add(2, 5);
$comp->sub(2, 5);
CComponent透過__get、__set和__call這3個魔術方法(這3個魔術方法的使用詳見:PHP基礎之類和物件13-重載)來實現「行為類別綁定」這個特性,當呼叫CComponent類別不存在的成員變數和成員方法的時候,CComponent類別會通過這三個魔法方法在「動態綁定的行為物件」上進行查找。即將不存在的成員變數和成員方法路由到「動態綁定物件」上。


Yii框架分析(五)-再談CComponent基礎類

可以用3句話來總結CComponent類別的特性:
1、 更好的配置一個對象,當設定對象的成員變數的時候,其實是運行一段程式碼;
2、 更好更好的監聽一個對象,當對象的內部狀態改變的時候,其它對象可以得到通知;
3、 更好的擴展一個對象,可以給一個對象增加成員變量和成員函數,還能監聽這個對象的狀態。

 以上就是Yii框架分析(五)-再談CComponent基礎類的內容,更多相關內容請關注PHP中文網(www.php.cn)!


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