Played { gameId = 55555; playerId = 48939; position = (25, A); shape = Square }
--
You received this message because you are subscribed to the Google Groups "DDD/CQRS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+u...@googlegroups.com.
Visit this group at https://groups.google.com/group/dddcqrs.
For more options, visit https://groups.google.com/d/optout.
sealed trait Command
case class StartNewGame(board: Board) extends Command
case class RemoveGroup(position: Position) extends Command
sealed trait Event
case class GameStarted(id: GameId, board: Board) extends Event
case class GroupRemoved(id: GameId, position: Position, board: Board, score: Int) extends Event
case class GameFinished(id: GameId) extends Event
"In my opinion the first approach has a major downside because it leads to duplication of domain logic." .Can you elaborate ?
Regarding your board example id put the board in ( or all changes to the board) unless its going to be 10s of Megs. Some message providers do fail with large messages. If it becomes a problem change it. .
"In my opinion the first approach has a major downside because it leads to duplication of domain logic." .Can you elaborate ?Yes, my original post is not very clear here.The game is a good example if we only include the position of the played move in the event: GroupRemoved(id: GameId, column: Int, row: Int).This approach is totally reasonable in a game like Tic-Tac-Toe because all the event handler does is to put a mark at the played position.However, with SameGame when a move is played the board rearranges in a non-trivial way according to the game rules. Should these rules be implemented twice, in the BL layer and in the event handler of the read side? This would be a duplication of domain logic.
It is always a good idea to ask for the justifying business requirements before adding complexity to a system. So, which requirements where the drivers for introducing ES and CQRS in the first place? What problem did you try to solve? One of your questions was, how to avoid duplication of business logic. I suggested an approach which puts logic first, in order to emitt relatively fine grained and meaningfull events. Handling those events should be very easy; it's merely apllying atomic changes to some sort of state. You can apply them to a given read model just the same way you apply them to your aggregates state in order to reconstitute it. So for example, your board read model is only interested in the rows / columns moved events; there is no need to worry about PointsMade or GameEnded in order to draw the board.
Adding complexity is a tradeoff, make shure you gain something worth the effort.
Thomas