Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Zend framework Zend-设计模式数据映射器&;表网关_Zend Framework_Design Patterns - Fatal编程技术网

Zend framework Zend-设计模式数据映射器&;表网关

Zend framework Zend-设计模式数据映射器&;表网关,zend-framework,design-patterns,Zend Framework,Design Patterns,这直接来自Zend快速入门指南。我的问题是:当getDbTable()方法分配一个默认的Zend\u Db\u Table对象时,为什么需要setDbTable()方法?如果您知道此映射程序使用特定的表,为什么还要提供通过setDbTable()使用“错误”表的可能性?如果剩余的代码(find(),fetchAll()等)特定于Guestbook,那么您可以通过设置表获得什么灵活性 class Application_Model_GuestbookMapper { protected

这直接来自Zend快速入门指南。我的问题是:当
getDbTable()
方法分配一个默认的
Zend\u Db\u Table
对象时,为什么需要
setDbTable()
方法?如果您知道此映射程序使用特定的表,为什么还要提供通过
setDbTable()
使用“错误”表的可能性?如果剩余的代码(
find()
fetchAll()
等)特定于
Guestbook
,那么您可以通过设置表获得什么灵活性

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';
}

此方法称为延迟加载。它允许属性在被请求之前保持为null,除非它被提前设置


setDbTable()
的一个用途是测试。通过这种方式,您可以设置一个模拟数据库表或类似的东西。

Phil是正确的,这被称为。我刚刚在最近的一个项目中实现了这个模式,因为它有以下好处:

  • 当我调用getMember()方法时,我将得到一个返回值,不管它之前是否设置过。这非常适合:
    $This->getCar()->getires()->getSize()

  • 此模式提供了灵活性,因为外部调用代码仍然能够设置成员值:
    $myClass->setCar(new Car())

--编辑--


在实现延迟加载设计模式时要小心。如果您的对象未正确水合,则会对每一条不可用的数据发出查询。最好的做法是在开发阶段跟踪数据库查询日志,以确保查询的数量和类型符合预期。我正在做的一个项目为一个“详细信息”页面发出了超过27个查询,直到我看到这些查询,我才知道。还有一个补充:如果
setDbTable()
仅用于延迟加载,那么将其设为私有是否更有意义?这样就避免了意外赋值,避免了Sam最初提到的错误表。 我们是否应该为了可测试性而牺牲设计