如何正确强制正确使用类方法?

Posted

技术标签:

【中文标题】如何正确强制正确使用类方法?【英文标题】:How to Properly Enforce Correct Usage of a Class Method? 【发布时间】:2009-10-19 16:26:45 【问题描述】:

我们当前的 ORM 解决方案使用数据映射器来表示数据库中的表/视图,然后返回一个 Collection 对象,该对象可用于将检索到的记录作为模型对象进行迭代。在数据映射器和模型层之间是一个存储库层,它处理对数据映射器的域请求并返回相应的集合或域对象。

我们目前正在考虑重构 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;
 

然后在这个版本中,Collection 对象将发出对 Repository 的调用,它可以首先搜索其缓存的对象,然后仅在需要时才向数据库发出调用以加载记录。

【问题讨论】:

【参考方案1】:

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

它部分取决于代码的上下文,但依赖于将存储库注入到您创建的 DataMapper 实例中,即:

$repo = new Repository();

$mapper = new DataMapper($repo);

将使您免于随后在您想使用 findAll() 时传递该 $repo。即:

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

我发现当参数成为我进行的每个函数调用的普遍部分时,考虑将它们转换为实例变量是有意义的(尤其是当它们每次都相同时)。

如果您的存储库因上下文/实例而异,则注入更有意义。如果您发现自己总是创建一个 repo 实例并希望回收它,那么单例可能是合适的。

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

【讨论】:

【参考方案2】:

我可能会做一些不同的事情。我会添加一个 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;

set 方法可能看起来像

public function setRepository(RepositoryInterface $repos)

    $this->_repository = $repos;

【讨论】:

以上是关于如何正确强制正确使用类方法?的主要内容,如果未能解决你的问题,请参考以下文章

每天30s系列|在 React 组件类中如何保证 `this` 为正确的上下文?

如何正确地将参数传递给 Django 中的基于类的视图实例?

Python 如何正确使用静态方法和类方法?

PHP接口类interface的正确使用方法

如何正确继承类方法

如何通过测试正确设置和拆卸我的 pytest 类?