Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/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
Php 如何使用数据映射器模式延迟加载子对象?_Php_Lazy Loading_Datamapper - Fatal编程技术网

Php 如何使用数据映射器模式延迟加载子对象?

Php 如何使用数据映射器模式延迟加载子对象?,php,lazy-loading,datamapper,Php,Lazy Loading,Datamapper,如果我有一个相当复杂的用户模型,我想使用数据映射模式来加载它,那么我如何在不让用户知道UserMapper的情况下懒洋洋地加载一些更密集的用户信息呢 例如,如果用户模型允许一个地址对象数组(用户可能有很多地址对象,但不一定需要提前),那么如果需要,我将如何加载这些对象 我是否让用户模型知道AddressMapper 我是否将用户模型传递回UserMapper,然后UserMapper将只包含地址 有更好的选择吗?好吧,我曾经发现了以下聪明的模式,感谢Zend框架的开发人员。事情是这样的: cla

如果我有一个相当复杂的用户模型,我想使用数据映射模式来加载它,那么我如何在不让用户知道UserMapper的情况下懒洋洋地加载一些更密集的用户信息呢

例如,如果用户模型允许一个地址对象数组(用户可能有很多地址对象,但不一定需要提前),那么如果需要,我将如何加载这些对象

我是否让用户模型知道AddressMapper

我是否将用户模型传递回UserMapper,然后UserMapper将只包含地址


有更好的选择吗?

好吧,我曾经发现了以下聪明的模式,感谢Zend框架的开发人员。事情是这样的:

class ModelRelation
    implements IteratorAggregate
{
    protected $_iterator;
    protected $_mapper;
    protected $_method;
    protected $_arguments;

    public function __construct( MapperAbstract $mapper, $method, array $arguments = array() )
    {
        $this->_mapper    = $mapper;
        $this->_method    = $method;
        $this->_arguments = $arguments;
    }

    public function getIterator()
    {
        if( $this->_iterator === null )
        {
            $this->_iterator = call_user_func_array( array( $this->_mapper, $this->_method ), $this->_arguments );
        }

        return $this->_iterator;
    }

    public function __call( $name, array $arguments )
    {        
        return call_user_func_array( array( $this->getIterator(), $name ), $arguments );
    }
}
class UserMapper
    extends MapperAbstract
{
    protected $_addressMapper;

    public function __construct( AddressMapper $addressMapper )
    {
        $this->_addressMapper = $addressMapper;
    }

    public function getUserById( $id )
    {
        $userData = $this->getUserDataSomehow();

        $user = new User( $userData );
        $user->addresses = new ModelRelation(
            $this->_addressesMapper,
            'getAddressesByUserId',
            array( $id )
        );

        return $user;
    }
}

class AddressMapper
    extends MapperAbstract
{
    public function getAddressesByUserId( $id )
    {
        $addressData = $this->getAddressDataSomehow();

        $addresses = new SomeAddressIterator( $addressData );

        return $addresses;
    }
}

$user = $userMapper->getUserById( 3 );
foreach( $user->addresses as $address ) // calls getIterator() of ModelRelation
{
    // whatever
}
Ben Scholzen的实际实施

您使用它的方式如下:

class ModelRelation
    implements IteratorAggregate
{
    protected $_iterator;
    protected $_mapper;
    protected $_method;
    protected $_arguments;

    public function __construct( MapperAbstract $mapper, $method, array $arguments = array() )
    {
        $this->_mapper    = $mapper;
        $this->_method    = $method;
        $this->_arguments = $arguments;
    }

    public function getIterator()
    {
        if( $this->_iterator === null )
        {
            $this->_iterator = call_user_func_array( array( $this->_mapper, $this->_method ), $this->_arguments );
        }

        return $this->_iterator;
    }

    public function __call( $name, array $arguments )
    {        
        return call_user_func_array( array( $this->getIterator(), $name ), $arguments );
    }
}
class UserMapper
    extends MapperAbstract
{
    protected $_addressMapper;

    public function __construct( AddressMapper $addressMapper )
    {
        $this->_addressMapper = $addressMapper;
    }

    public function getUserById( $id )
    {
        $userData = $this->getUserDataSomehow();

        $user = new User( $userData );
        $user->addresses = new ModelRelation(
            $this->_addressesMapper,
            'getAddressesByUserId',
            array( $id )
        );

        return $user;
    }
}

class AddressMapper
    extends MapperAbstract
{
    public function getAddressesByUserId( $id )
    {
        $addressData = $this->getAddressDataSomehow();

        $addresses = new SomeAddressIterator( $addressData );

        return $addresses;
    }
}

$user = $userMapper->getUserById( 3 );
foreach( $user->addresses as $address ) // calls getIterator() of ModelRelation
{
    // whatever
}
事情是这样的;如果对象图在某一点变得非常复杂和嵌套很深,这可能会变得非常缓慢,因为映射程序都必须查询自己的数据(假定您使用数据库进行持久化)。当我将此模式用于CMS以获取嵌套的
页面
对象(任意深度的子页面)时,我遇到了这种情况

它可能会被一些缓存机制调整,以大大加快速度