溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Object和Component的區(qū)別是什么

發(fā)布時間:2021-08-04 15:20:55 來源:億速云 閱讀:147 作者:Leah 欄目:數(shù)據(jù)庫

這篇文章給大家介紹Object和Component的區(qū)別是什么,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

  由于Componet引入了事件、行為,因此,它并非簡單繼承了Object的屬性實(shí)現(xiàn)方式,而是基于同樣的機(jī)制, 重載了 __get() __set() 等函數(shù)。但從實(shí)現(xiàn)機(jī)制上來講,是一樣的。這個不影響理解。

  前面說過,官方將Yii定位于一個基于組件的框架??梢娊M件這一概念是Yii的基礎(chǔ)。 如果你有興趣閱讀Yii的源代碼或是API文檔,你將會發(fā)現(xiàn), Yii幾乎所有的核心類都派生于(繼承自) yii\base\Component 。

  在Yii1.1時,就已經(jīng)有了component了,那時是 CComponent。Yii2將Yii1.1中的CComponent拆分成兩個類: yii\base\Object 和 yii\base\Component 。

  其中,Object比較輕量級些,通過getter和setter定義了類的屬性(property)。 Component派生自O(shè)bject,并支持事件(event)和行為(behavior)。因此,Component類具有三個重要的特性:屬性(property)、事件(event)、行為(behavior)。

  相信你或多或少了解過,這三個特性是豐富和拓展類功能、改變類行為的重要切入點(diǎn)。 因此,Component在Yii中的地位極高。

  在提供更多功能、更多便利的同時,Component由于增加了event和behavior這兩個特性, 在方便開發(fā)的同時,也犧牲了一定的效率。 如果開發(fā)中不需要使用event和behavior這兩個特性,比如表示一些數(shù)據(jù)的類。 那么,可以不從Component繼承,而從Object繼承。 典型的應(yīng)用場景就是如果表示用戶輸入的一組數(shù)據(jù),那么,使用Object。 而如果需要對對象的行為和能響應(yīng)處理的事件進(jìn)行處理,毫無疑問應(yīng)當(dāng)采用Component。 從效率來講,Object更接近原生的PHP類,因此,在可能的情況下,應(yīng)當(dāng)優(yōu)先使用Object。

  Object的配置方法

  Yii提供了一個統(tǒng)一的配置對象的方式。這一方式貫穿整個Yii。Application對象的配置就是這種配置方式的體現(xiàn):

  $config = yii\helpers\ArrayHelper::merge(

  require(__DIR__ . '/../../common/config/main.php'),

  require(__DIR__ . '/../../common/config/main-local.php'),

  require(__DIR__ . '/../config/main.php'),

  require(__DIR__ . '/../config/main-local.php')

  );

  $application = new yii\web\Application($config);

  $config 看著復(fù)雜,但本質(zhì)上就是一個各種配置項的數(shù)組。Yii中就是統(tǒng)一使用數(shù)組的方式對對象進(jìn)行配置,而實(shí)現(xiàn)這一切的關(guān)鍵就在 yii\base\Object 定義的構(gòu)造函數(shù)中:

  public function __construct($config = [])

  {

  if (!empty($config)) {

  Yii::configure($this, $config);

  }

  $this->init();

  }

  所有 yii\base\Object 的構(gòu)建流程是:

  構(gòu)建函數(shù)以 $config 數(shù)組為參數(shù)被自動調(diào)用。

  構(gòu)建函數(shù)調(diào)用 Yii::configure() 對對象進(jìn)行配置。

  在最后,構(gòu)造函數(shù)調(diào)用對象的 init() 方法進(jìn)行初始化。

  數(shù)組配置對象的秘密在 Yii::configure() 中,但說破了其實(shí)也沒有什么神奇的:

  public static function configure($object, $properties)

  {

  foreach ($properties as $name => $value) {

  $object->$name = $value;

  }

  return $object;

  }

  配置的過程就是遍歷 $config 配置數(shù)組,將數(shù)組的鍵作為屬性名,以對應(yīng)的數(shù)組元素的值對對象的屬性賦值。因此,實(shí)現(xiàn)Yii這一統(tǒng)一的配置方式的要點(diǎn)有:

  繼承自 yii\base\Object 。

  為對象屬性提供setter方法,以正確處理配置過程。

  如果需要重載構(gòu)造函數(shù),請將 $config 作為該構(gòu)造函數(shù)的最后一個參數(shù),并將該參數(shù)傳遞給父構(gòu)造函數(shù)。

  重載的構(gòu)造函數(shù)的最后,一定記得調(diào)用父構(gòu)造函數(shù)。

  如果重載了 yii\base\Object::init() 函數(shù),注意一定要在重載函數(shù)的開頭調(diào)用父類的 init() 。

  只要實(shí)現(xiàn)了以上要點(diǎn),就可以使得你編寫的類可以按照Yii約定俗成的方式進(jìn)行配置。這在編寫代碼的過程中,帶來許多便利。

  像你這么聰明的,肯定會提出來,如果配置數(shù)組的某個配置項,也是一個數(shù)組,這怎么辦? 如果某個對象的屬性,也是一個對象,而非一個簡單的數(shù)值或字符串時,又怎么辦?

  這兩個問題,其實(shí)是同質(zhì)的。如果一個對象的屬性,是另一個對象,就像Application里會引入諸多的Component一樣, 這是很常見的。如后面會看到的 $app->request 中的 request 屬性就是一個對象。 那么,在配置 $app 時,必然要配置到這個 reqeust 對象。 既然 request 也是一個對象,那么他的配置要是按照Yii的規(guī)矩來,也就是用一個數(shù)組來配置它。 因此,上面提到的這兩個問題,其實(shí)是同質(zhì)的。

  那么,怎么實(shí)現(xiàn)呢?秘密在于setter函數(shù)。由于 $app 在進(jìn)行配置時,最終會調(diào)用 Yii::configure() 函數(shù)。 該函數(shù)又不區(qū)分配置項是簡單的數(shù)值還是數(shù)組,就直接使用 $object->$name = $value 完成屬性的賦值。 那么,對于對象屬性,其配置值 $value 是一個數(shù)組,為了使其正確配置。 你需要在其setter函數(shù)上做出正確的處理方式。 Yii應(yīng)用 yii\web\Application 就是依靠定義專門的setter函數(shù),實(shí)現(xiàn)自動處理配置項的。 比如,我們在Yii的配置文件中,可以看到一個配置項 components ,一般情況下,他的內(nèi)容是這樣的:

  'components' => [

  'request' => [

  // !!! insert a secret key in the following (if it is empty) -

  // this is required by cookie validation

  'cookieValidationKey' => 'v7mBbyetv4ls7t8UIqQ2IBO60jY_wf_U',

  ],

  'user' => [

  'identityClass' => 'common\models\User',

  'enableAutoLogin' => true,

  ],

  'log' => [

  'traceLevel' => YII_DEBUG ? 3 : 0,

  'targets' => [

  [

  'class' => 'yii\log\FileTarget',

  'levels' => ['error', 'warning'],

  ],

  ],

  ],

  'errorHandler' => [

  'errorAction' => 'site/error',

  ],

  ],

  這是一個典型嵌套配置數(shù)組。那么Yii是如何把他們配置好的呢? 聰明的你肯定想到了,Yii一定是定義了一個名為 setComponents 的setter函數(shù)。 當(dāng)然,Yii并未將該函數(shù)放在 yii\web\Application 里,而是放在父類 yii\di\ServiceLocator 里面。 至于 ServiceLocator 是何方神圣,在后面 服務(wù)定位器(Service Locator) 部分會講到, 這里你只需要知道它是Application的父類,提供components屬性的setter方法就可以了:

  public function setComponents($components)

  {

  foreach ($components as $id => $component) {

  $this->set($id, $component);

  }

  }

  這里有個成員函數(shù), $this->set() ,他是服務(wù)定位器用來注冊服務(wù)的方法。 我們暫時不講這個東西,留待 服務(wù)定位器(Service Locator) 部分再講。 現(xiàn)在只要知道這個函數(shù)把配置文件中的 components 配置項搞定就可以了。

  從 yii\base\Object::__construct() 來看,對于所有Object,包括Component的屬性,都經(jīng)歷這么4個階段:

  預(yù)初始化階段。這是最開始的階段,就是在構(gòu)造函數(shù) __construct() 的開頭可以設(shè)置property的默認(rèn)值。

  對象配置階段。也就是前面提到構(gòu)造函數(shù)調(diào)用 Yii::configure($this, $config) 階段。 這一階段可以覆蓋前一階段設(shè)置的property的默認(rèn)值,并補(bǔ)充沒有默認(rèn)值的參數(shù),也就是必備參數(shù)。 $config 通常由外部代碼傳入或者通過配置文件傳入。

  后初始化階段。也就是構(gòu)造函數(shù)調(diào)用 init() 成員函數(shù)。 通過在 init() 寫入代碼,可以對配置階段設(shè)置的值進(jìn)行檢查,并規(guī)范類的property。

  類方法調(diào)用階段。前面三個階段是不可分的,由類的構(gòu)造函數(shù)一口氣調(diào)用的。 也就是說一個類一但實(shí)例化,那么就至少經(jīng)歷了前三個階段。 此時,該對象的狀態(tài)是確定且可靠的,不存在不確定的property。 所有的屬性要么是默認(rèn)值,要么是傳入的配置值,如果傳入的配置有誤或者沖突,那么也經(jīng)過了檢查和規(guī)范。 也就是說,你就放心用吧。

關(guān)于Object和Component的區(qū)別是什么就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI