This session is about rules & behavior at the place that holds the data. We will work our way up from value objects to services and consider the pro, con and grey area design choices along the way.
Do you want to learn what exactly the function of an aggregate is? Then join me for a discussion on boundaries, message passing, and role play.
41. @pelshoff
final class RegistrationService
{
private MeetingRepository $meetingRepository;
private AttendeeRepository $attendeeRepository;
private RegistrationRepository $registrationRepository;
public function __construct(/**/) {/**/}
public function registerAttendee(Uuid $meetingId, Uuid $attendeeId): void
{
$meeting = $this->assertMeertingExists($meetingId);
$attendee = $this->assertAttendeeIsNotImaginary($attendeeId);
$listOfAttendees = $this->attendeeRepository->listAttendeesFor($meetingId);
$context = new RegisterNewAttendee($meeting, $listOfAttendees);
$registration = $context->register($attendee);
$this->registrationRepository->save($registration);
}
}
42. @pelshoff
final class RegisterNewAttendee
{
private Meeting $meeting;
private ListOfRegistrations $registrations;
/**/
public function register(Attendee $attendee): Registration
{
$this->assertAttendeeIsNotRegistered($attendee);
return $this->meeting->register($attendee->getId());
}
private function assertAttendeeIsNotRegistered(Attendee $attendee)
{
if ($this->registrations->isAttendeeRegistered($attendee->getId())) {
throw CouldNotRegisterAttendee::becauseAttendeeWasPreviouslyRegistered(
$this->meeting->getId(),
$attendee->getId()
);
}
}
}
43. @pelshoff
1, 2...
// Integration/DB or Unit+Mock
function testThatNewRegistrationsAreSaved()
function testThatRegistrationsAreUpdatedAndSaved()
function testThatXyAndZAndSaved()
many
// Integration/DB
function testThatTheAggregateCanBeSaved()
function testThatSpecialCircumstancesAlsoIntegrateWell()
// Unit
function testThatBusinessLogicWorksAsExpected()
function testThatTheyDontRequireManyMocks()
function testThatIfEvenAnyAtAll()
function testThatItMakesYouHappierAndMoreProductive()
44. @pelshoff
Service Aggregate Service+Context
Performance + - +/-
Code overhead +/- + -
Infra complexity + +/- +
Unit testing - + +
Consistency Eventual Transactional It depends
Conclusion For simple cases
(most)
For transactional
boundaries
For complex cases
46. @pelshoff
Heuristics
anything that provides a plausible aid or direction in the solution of a problem but is in the final analysis
unjustified, incapable of justification, and potentially fallible.
-Billy Vaughn Koen
https://www.dddheuristics.com/