这是一个非常常见且很容易解决的问题,但您需要退后一步。
您基本上应该有两个有界上下文 - 保留和资源。
保留不能访问任何其他有界上下文的任何类/服务/对象,因为它违反了封装规则。
您应该改为在 resources 有界上下文中创建查询处理程序。
resources 应该共享查询和响应类,它们将提供您需要的信息 - 公共 API,它是您的域之间的合同。最重要的是,reservations bounded context 不应该知道 resources 的任何实现细节。
PHP 中的示例:
资源域:
请求信息:
class IsResourceAvaiableQuery
{
private int $resourceId;
__construct(int $resourceId)
{
$this->resourceId = $resourceId;
}
public function getResourceId(): int
{
return $this->resourceId;
}
}
要获得一个不应该是简单类型,而是由类表示的响应:
class IsResourceAvaiableDTO
{
private bool $isAvailable;
__construct(bool $isAvailable)
{
$this->isAvailable = $isAvailable;
}
public function isAvailable(): bool
{
return $this->isAvailable;
}
}
请注意,查询和响应 DTO 都是不可变对象 - 您不能改变它们的状态。
现在在 reservation 域中:
class ReservationValidator
{
public function validate(Reservation $reservation): ViolationsList
{
$isResourceAvailableQuery = new IsResourceAvaiableQuery($reservation->getResourceId());
$isResourceAvailableDTO = $this->messageBus->query($isResourceAvailableQuery);
if (false === $isResourceAvailableDTO->isAvailable()) {
// mark $reservation as invalid
}
}
}
总结
这样您就有了一个单一的事实来源,并且 reservation 域不需要知道您如何确定资源是否可用。此外,您可以随时更改实现,只要您不更改合同(IsResourceAvaiableQuery & IsResourceAvaiableDTO),它就不会影响 reservations 域。
请注意,资源可能在两个域中以不同的方式可用,您也需要进行拆分:
-
资源 - 可供预订 - 存在并标记为可操作的项目
-
reservations - 项目尚未预订。而且您需要合并来自两个域的决策才能全面了解情况。