2011-09-27 7 views
3

데이터 맵핑 패턴을 사용하여로드하려는 사용자 모델이 상당히 복잡한 경우 사용자가 UserMapper를 인식하지 못하도록 사용자 정보를 집중적으로로드하지 않는 것이 어떻습니까?Data Mapper 패턴을 사용하여 자식 개체를 느리게로드하는 방법은 무엇입니까?

예를 들어, User 모델에서 Address 객체의 배열을 허용하는 경우 (사용자가 그 중 많은 수는 가질 수 있지만 꼭 필요한 것은 아닙니다), 필요한 경우 해당 객체를 어떻게로드합니까?

사용자 모델이 AddressMapper를 인식하도록합니까?

사용자 모델을 UserMapper로 전달하고 UserMapper는 주소 만 수화합니까?

더 좋은 옵션이 있습니까?

답변

7

젠드 프레임 워크 용 개발자 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); 
    } 
} 

벤 Scholzen의 실제 구현 is here : 그것은 이런 식입니다. 당신이 그것을 사용하는 것이

방법은,이 같은 것입니다 :

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에 중첩 된 Pages 개체 (임의로 깊은 하위 페이지)를 가져 왔을 때이 기능을 경험했습니다.

일을 상당히 빠르게하기 위해 일부 캐싱 메커니즘으로 조정할 수 있습니다.

관련 문제