Skip to content

Instantly share code, notes, and snippets.

@AntonStoeckl
Last active March 28, 2022 13:18
Show Gist options
  • Save AntonStoeckl/f710f0312a96ef832e76531af2489528 to your computer and use it in GitHub Desktop.
Save AntonStoeckl/f710f0312a96ef832e76531af2489528 to your computer and use it in GitHub Desktop.
Example for blog post: Domain-Driven Design vs. "Functional Core, Imperative Shell"
package finishcard
import (
"ace-life/errtypes"
"ace-life/hexagon/domain"
"ace-life/hexagon/domain/player"
"ace-life/hexagon/events"
"ace-life/hexagon/usecases"
)
func FinishCard(
eventStream domain.EventStream,
command Command,
drawReplacementCard usecases.ForDrawingReplacementCards,
) domain.Event {
hand := reconstituteFrom(eventStream)
// check if the card-to-finish exists in the player's hand
finishedCard, err := hand.CardBy(command.CardID)
if err != nil {
return events.BuildFinishCardFailed(
command.PlayerID,
command.CardID,
errtypes.ResourceNotFound(err),
command.MessageID,
command.CurrentTime,
)
}
// try to draw a uniqe replacement card
replacementCard, err := drawReplacementCard(hand.CardIDs()...)
if err != nil {
return events.BuildFinishCardFailed(
command.PlayerID,
command.CardID,
errtypes.ExternalConstraintNotFulfilled(err),
command.MessageID,
command.CurrentTime,
)
}
// all fine
return events.BuildCardFinished(
command.PlayerID,
finishedCard,
replacementCard,
command.MessageID,
command.CurrentTime,
)
}
func reconstituteFrom(eventStream domain.EventStream) player.Hand {
var hand player.Hand
for _, event := range eventStream.Events {
switch actualEvent := event.(type) {
case events.PlayerEnrolled:
hand = player.BuildHand(
actualEvent.Card1,
actualEvent.Card2,
actualEvent.Card3,
)
case events.CardFinished:
hand = hand.ReplaceCard(
actualEvent.FinishedCard.ID,
actualEvent.ReplacementCard,
)
case events.CardRejected:
hand = hand.ReplaceCard(
actualEvent.RejectedCard.ID,
actualEvent.ReplacementCard,
)
}
}
return hand
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment