为简单起见,让我们假设一个应用程序具有Accounts
和Users
。每个帐户可以有任意数量的用户。还有3个消费者UserRepository
:
- 可以列出所有用户的管理界面
- 可以列出所有用户的公共前端
- 一个账户认证的 API,它应该只列出它自己的用户
假设UserRepository
是这样的:
class UsersRepository extends DatabaseAbstraction {
private function query() {
return $this->database()->select('users.*');
}
public function getAll() {
return $this->query()->exec();
}
// IMPORTANT:
// Tons of other methods for searching, filtering,
// joining of other tables, ordering and such...
}
记住上面的评论,以及抽象用户查询条件的必要性,我应该如何处理过滤用户的查询account_id
?我可以描绘出三种可能的道路:
1.我应该创建一个AccountUsersRepository
吗?
class AccountUsersRepository extends UserRepository {
public function __construct(Account $account) {
$this->account = $account;
}
private function query() {
return parent::query()
->where('account_id', '=', $this->account->id);
}
}
这样做的好处是减少了UsersRepository
方法的重复,但不太适合我迄今为止读过的关于 DDD 的任何内容(顺便说一下,我是菜鸟)
2.我应该把它作为一种方法AccountsRepository
吗?
class AccountsRepository extends DatabaseAbstraction {
public function getAccountUsers(Account $account) {
return $this->database()
->select('users.*')
->where('account_id', '=', $account->id)
->exec();
}
}
这需要复制所有UserRepository
方法,并且可能需要UserQuery
另一层,以链式方式实现这些查询逻辑。
3. 我应该UserRepository
从我的账户实体中查询吗?
class Account extends Entity {
public function getUsers() {
return UserRepository::findByAccountId($this->id);
}
}
这对我来说更像是一个聚合根,但引入了UserRepository
对Account
实体的依赖,这可能违反了一些原则。
4. 还是我完全没有抓住重点?
也许有更好的解决方案?
脚注:除了权限是一个服务问题之外,据我了解,他们不应该实现 SQL 查询,而是将其留给存储库,因为它们甚至可能不是 SQL 驱动的。