2009-10-19 92 views
0

我们当前的ORM解决方案使用数据映射器来表示数据库中的表/视图,然后返回一个Collection对象,该对象可用于遍历检索到的记录作为Model对象。 Data Mapper和Model层之间是一个Repository层,它处理对数据映射器的域请求并返回相应的集合或域对象。如何正确执行类方法的正确使用?

我们目前正在研究重构Repository和Data Mapper层的职责,以便所有到Data Mapper层的应用程序请求通过Repository进行路由,Data Mapper将检索到的数据行返回到Repository,然后返回必要的收集到请求的对象。

我想知道的是,将整个Repository对象传递给相应的Data Mapper是否有效/好做法,以便我们只能通过Repository层强制访问Data Mapper。

举个例子,这基本上它是如何工作现在:

class DataMapper { 

public function findAll(Criteria $criteria) 
{ 
    $select = $criteria->getSelect(); 

    // Build specific select statement 

    $rows = $this->_fetchAll($select); 

    return new Collection(array('data' => $rows, 'mapper' => get_class($this))); 
} 
} 

我想这样做是这样的:

class Repository { 

public function findAllByName(Model $model) 
{ 
    $this->_criteria->addCondition('name LIKE ?', $model->name); 

    $rows = $this->_mapper->findAll($this); 

    return new Collection(array('data' => $rows, 'repository' => get_class($this))); 
} 

} 

class DataMapper { 

public function findAll(Repository $repository) 
{ 
    $select = $repository->getCriteria()->getSelect(); 

    // Build specific select statement 

    $rows = $this->_fetchAll($select); 

    return $rows; 
} 
} 

然后在这个版本中,集合对象会发出一个电话到存储库,它可以首先搜索它的缓存对象,然后只发出对数据库的调用,以便在需要时加载记录。

回答

1

克里斯有一个有效的建议。

这部分地取决于代码的情况下,但依赖注入库到您所创建的DataMapper的情况下,即:

$repo = new Repository(); 

$mapper = new DataMapper($repo); 

将随后有,每当你想通过周围是$回购饶你使用findAll()。 IE:

$mapper->findAll(); 
$mapper->findAllByName(); 

我发现,当参数成为每一个函数调用我做的一个无处不在的一部分,这是有道理的考虑把他们变成实例变量(特别是当他们每次是相同的)。

如果您的存储库因上下文/实例不同而不同,那么注入更有意义。如果你发现你总是创建一个回购实例并且想要回收它,那么一个单例可能是合适的。

依赖注入的好处是它确实阐明了这种依赖性思想(具有讽刺意味!)。如果你想强制执行它,你可以在__construct()方法中做一些事情,如$ repo对象为空或者不是Repository实例时抛出一个异常。

1

我也许会做这个有点不同。我会添加一个setRepository(Repository $ repos)方法以及一个getRepository()方法。然后,在你的findAll方法中,调用getRepository()。如果尚未调用setRepository(),则getRepository可以返回默认存储库实例。

我也可能会为Repository类创建一个接口,以便可以在DataMapper类中使用Repository的不同实现。

所以get方法可能看起来像

public function getRepository() 
{ 
    if (!$this->_repository) { 
     $this->_repository = new Repository(); 
    } 

    return $this->_repository; 
} 

和设置方法可能看起来像

public function setRepository(RepositoryInterface $repos) 
{ 
    $this->_repository = $repos; 
}