2012-02-09 17 views
4

這是直接在Zend Quick Start指南之外。我的問題是:爲什麼當getDbTable()方法分配默認的Zend_Db_Table對象時,您需要setDbTable()方法?如果你知道這個映射器使用了一個特定的表格,爲什麼還要通過setDbTable()提供可能使用「錯誤」表格的可能性?如果剩餘的代碼(find(),fetchAll()等)特定於Guestbook,則可以通過設置表獲得什麼靈活性?Zend - 設計模式DataMapper和表格網關

class Application_Model_GuestbookMapper 
{ 
    protected $_dbTable; 

    public function setDbTable($dbTable) 
    { 
     if (is_string($dbTable)) { 
      $dbTable = new $dbTable(); 
     } 
     if (!$dbTable instanceof Zend_Db_Table_Abstract) { 
      throw new Exception('Invalid table data gateway provided'); 
     } 
     $this->_dbTable = $dbTable; 
     return $this; 
    } 

    public function getDbTable() 
    { 
     if (null === $this->_dbTable) { 
      $this->setDbTable('Application_Model_DbTable_Guestbook'); 
     } 
     return $this->_dbTable; 
    } 

    ... GUESTBOOK SPECIFIC CODE ... 
} 

class Application_Model_DbTable_Guestbook extends Zend_Db_Table_Abstract 
{ 
    protected $_name = 'guestbook_table'; 
} 

回答

3

菲爾是正確的,這就是所謂的lazy-loading design pattern。我剛剛實施了最近的一個項目這個模式,因爲這些好處:

  • 當我呼籲getMember()方法,我會得到一個返回值,如果不管它之前已經或沒有設置。這對於method chaining是偉大的:$this->getCar()->getTires()->getSize();

  • 這種模式在外面調用代碼提供了靈活性仍然能夠設置成員值:$myClass->setCar(new Car());

- 編輯 -

謹慎使用時實施延遲加載設計模式。如果您的對象沒有適當地保溼,則將針對每個不可用的數據發出查詢。最好的做法是在開發階段尾巴數據庫查詢日誌,以確保查詢的數量和類型是您所期望的。我正在處理的一個項目發出了超過27個查詢「詳細信息」頁面,直到我看到查詢時才知道。

1

該方法稱爲延遲加載。它允許一個屬性保持空值直到被請求,除非它被設置得更早。

setDbTable()的一種用法是測試。這樣你可以設置一個模擬數據庫表或類似的東西。

0

另外一個:如果setDbTable()僅用於延遲加載,將它設置爲私有更合理嗎?這樣可以避免Sam最初提到的意外分配和錯誤的表格。 爲了可測性,我們是否應該妥協設計?