0

我正在开发电动汽车充电站管理系统,连接了几个Charging Stations,我陷入了僵局。在这个领域中,我提出了 的聚合Charging Station,其中包括的内部状态Charging Station(是否已连接,其连接器的内部状态)。

它有一种UnlockConnector方法,为了准确尊重其名称(而不是贫血),它将请求发送到相应的Charging Station,因为它是我的域的中心,以了解 的Charging Station连接性并将请求发送到物理Charging Station

type Connector struct {
  Status string
}

type ChargingStation struct {
  Connected bool
  Connectors []Connector
  URL string
  ...
}

func (station *ChargingStation) UnlockConnector(connectorID int, stationClient service.StationClient) error {
  if !station.Connected {
    return errors.New("charging station is not connected")
  }
  connector := station.Connectors[connectorID]
  if connector.Status != "Available" {
    return errors.New("connector is not available to be unlocked")
  }
  err := stationClient.SendUnlockConnectorRequest(station.URL, connectorID)
  if err != nil {
    return errors.New("charging station rejected the request")
  }
  station.On(event.StationConnectorUnlocked{
    ConnectorID: connectorID,
    Timestamp: time.Now(),
  })
  return nil
}

而且我想出了另一个聚合,它代表Charging Session用户和用户之间的Charging Station交互Connector。a 的创建Charging Session完全与Connector' 状态相结合,即如果Connector已经被用户解锁,则创建会话,如果Connector' 的能量流已停止,则已Charging Session结束。

不管它们如何耦合,Charging Session实体似乎不属于Charging Station聚合,因为它没有回答主要问题:当一个 Station 被删除时,它Charging Session的 s 是否也应该被删除?)还有,我什么时候会支付此会话中消耗的能量,它与 Station Aggregate Context 没有任何关系。

我想创建一个SessionCreator域服务,以确保当 aCharging StationConnector解锁时, aCharging Session也将被创建:

type SessionCreator interface {
  CreateSession(station *station.Station, connectorID int, sessionID int) error
}

type sessionCreator struct {
  stationClient StationClient
}

type (svc sessionCreator) CreateSession(station *station.Station, connectorID int, userID string, sessionID int) error {
  err := station.UnlockConnector(connectorID, svc.stationClient)
  if err != nil {
    return err
  }
  session.Create(sessionID, station.ID, connectorID, userID)
  return nil
}

但是它只是感觉有点奇怪,并且不能完全满足其他不变量(当连接器的能量流停止时,它必须结束会话),我虽然也制作了一个监听事件的事件监听器StationConnectorUnlocked,但我只是不知道哪个是理想的方式。

4

1 回答 1

1

从我对问题的理解来看,我认为你的聚合Charging StationCharging Session正确的。你说它们都是耦合的,但在我看来Charging Station不需要知道 Session 的存在,而 Session 也不需要知道任何关于 Station 内部的事情,所以对我来说耦合是低的。

关于您关于在 Station 上发生事情时如何创建和修改会话的问题,根据您的措辞,解决方案对我来说似乎很清楚:

如果连接器已被用户解锁,则创建会话,如果连接器的能量流已停止,则充电会话已结束

突出显示的词是业务事件。你可以这样画:

  • ConnectorUnlocked --> ChargingSessionCreated
  • ConnectorEnergyFlowStopped --> ChargingSessionEnded

我实现这一点的方式是使用发布/订阅系统,因此在状态更改和订阅者触发用例之后聚合发布事件,这可能会对聚合执行操作,最终可能会发布事件。

这种方法的分布式特性使得跟踪整个系统上发生的事情变得更加困难,因为解锁连接器和创建会话不会发生在一个地方。它们可能会发生在系统的两个不同部分。好处是,随着时间的推移,利益相关者可以提出许多在连接器解锁时需要发生的事情,而您只需要继续向现有事件添加订阅者即可。

于 2020-04-30T22:10:20.770 回答