这是一个非常常见且易于解决的问题,但您需要退后一步。
您基本上应该有两个有界上下文 - 保留和资源。保留不能访问任何其他有界上下文的任何类/服务/对象,因为它违反了封装规则。
相反,您应该在资源有界上下文中创建一个查询处理程序。这些资源应该共享查询和响应类,它们将提供您需要的信息——公共 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 都是不可变对象 - 您不能改变它们的状态。
现在在预订域中:
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
}
}
}
概括
这样,您就有了一个单一的事实来源,并且保留域不需要知道您如何确定资源是否可用。此外,您可以随时更改实现,只要您不更改合同(IsResourceAvaiableQuery & IsResourceAvaiableDTO) ,它就不会影响预订域。
请注意,资源可能在两个域中以不同的方式可用,您也需要进行拆分:
- 资源- 可供预订 - 存在并标记为可操作的项目
- 预订- 项目尚未预订。您需要合并来自两个域的决策才能全面了解情况。