Dotarłem do miejsca w którym powstał kod. Oczywiście jak to jest w tych czasach korzystałem z pomocy Copilota.
Do rzeczy, na warsztat został wzięty agregat Zmiana Grupy Startowej przez Zawodnika.
Widoczny pod tym adresem:
Wyszedł prawie idealnie, powstał prosty agregat jeden command jeden event, kilka reguł. Tu należy się uwaga, ten ES powstał jakieś cztery lata temu, razem z kolegami szkoliliśmy się w event stormingu padło na maraton, akurat ten temat był mi dobrze znany.
Kod jest polsko angielski, cóż tak uznałem, że będzie wygodniej na tę chwilę.
Opis:
Do zmiany grupy dochodzi na pewien czas przed startem maratonu, z reguły było to około miesiąca przed dniem startu. Następuje wtedy wygenerowanie grup startowych, które składają się docelowo z 15 zawodników. Istotnym faktem, który nie jest poruszany w tym kontekście ale należy go nadmienić jest to, że zawodnik który rejestruje się w danej edycji maratonu nie jest nazywany zawodnikiem a uczestnikiem.
Dlaczego to jest istotne? Uczestnik staje się zawodnikiem w momencie opłacenia startu, wtedy też uczestnik otrzymuje numer startowy, który uprawnia go do startu w zawodach oraz dzięki nie mu przynależy do jakieś grupy. Czyli jedną z reguł jest to, że do grupy startowej należą tylko zawodnicy.
Dlaczego to nie jest istotne dla tego agregatu? Dlatego że ten agregat umiejscowiony jest po fakcie wygenerowania grup. Dla niego fakt ten nie jest istotny, a są istotne inne reguły ale sama informacja jest ważna dla całego kontekstu zarządzania grupami startowymi i zrozumienia całego procesu.
Reguły
- grupy startowe muszą być wygenerowane - ta reguła w tym kontekście to typ "must be", bez wygenerowanych grup nie może odbyć się zmiana grupy, czyli brak spełnienia tej reguły eliminuje całość, nie da się jej nagiąc,
- nie przekroczono terminu zmian grupy - tu sprawa nie jest oczywista, termin jest płynny w zależności od edycji maratonu ale nie zmienia to faktu, że tylko w tym terminie można zmienić grupę *.
- Grupa docelowa jest z tego samego dystansu - to jest ważna reguła, której nie da się ominąć, czyli mamy kolejne "must be", dlaczego? grupy na danym dystansie startują o wyznaczonych porach, zapomniałem nadmienić że to maraton 24H, ta reguła została stworzona z przyczyn organizacyjnych,
- Zawodnik nie zmieniał wcześniej grupy - reguła, ograniczenie ilości zmian, czy zawsze musi być spełniona? no to już zależy ale bardziej od reguł dotyczących danej edycji zawodów *.
- Grupa docelowa musi mieć miejsce - to dość logiczna reguła, która musi być spełniona, gdyż grupy mają narzuconą ilość zawodników, która ma tam być ale czy nie ma odstępstw? *.
Kod dostępny jest w tym miejscu
public class ZmianaGrupyApplicationService
{
private readonly IGrupaRepository _grupaRepo;
private readonly IZawodnikRepository _zawodnikRepo;
public ZmianaGrupyApplicationService(
IGrupaRepository grupaRepo,
IZawodnikRepository zawodnikRepo)
{
_grupaRepo = grupaRepo;
_zawodnikRepo = zawodnikRepo;
}
public void ZmienGrupe(ZmianaGrupyCommand command)
{
// 1. Pobierz dane
var zawodnik = _zawodnikRepo.GetById(command.ZawodnikId);
var grupaWyjsciowa = _grupaRepo.GetById(command.GrupaWyjsciowaId);
var grupaDocelowa = _grupaRepo.GetById(command.GrupaDocelowaId);
// 2. Utwórz agregat domenowy
var zmiana = new ZmianaGrupyStartowej(
command.TerminGrupy,
zawodnik,
grupaWyjsciowa,
grupaDocelowa
);
// 3. Wykonaj operację domenową
try
{
zmiana.ZmienGrupe();
}
catch (Exception ex)
{
//save to log
throw;
}
// 4. Zapisz zmiany
_zawodnikRepo.Save(zawodnik);
_grupaRepo.Save(grupaWyjsciowa);
_grupaRepo.Save(grupaDocelowa);
}
}
Nie będę ukrywał, copilot przyszedł mi z pomocą w tworzeniu tego serwisu, mój prototyp był nie co mniej "ładny".
Agregat sprawdza reguły
public void ZmienGrupe()
{
ValidateTermin();
ValidateDystanse();
ValidateZawodnik();
ValidateIloscMiejsc();
// Wykonaj zmianę na encjach
_zawodnik.ZmienGrupe(_grupaDocelowa);
_grupaWyjsciowa.UsunZawodnika(_zawodnik);
_grupaDocelowa.DodajZawodnika(_zawodnik);
}
Sprawdzenie reguł:
- Nie przekroczono terminu zmian grupy - mogła zaistnieć sytuacja, pojedyncze przypadki, że tuż przed startem jakaś osoba mogła być przeniesiona z jednej grupy do drugiej, tak więc ta reguła może zostać podważona, ale to zawsze musiała być zgoda sędziego zawodów. Ciekawe jak to przedstawić w kodzie? (mamy rolę sędziego, to może być ciekawe)
- Zawodnik nie zmieniał wcześniej grupy - ta reguła mogła by być nagięta w sytuacji gdy zawodnik przed startem zgłasza że zmienia dystans, rezygnuje z jednego i pojedzie na innym dystansie, dzieje się to po wygenerowaniu i zatwierdzeniu grup, sądzę, że ten proces jest inny i zasługuje na osobny agregat, reguły będą musiały być zbadane w szerszym zakresie, albo przypadek taki że kierownik zawodów ma jakąś znajomą osobę która jednak chciał by zmienić grupę, bo zapisała się już po zmianie grup i co odmówisz?
- Grupa docelowa musi mieć miejsce - ta reguła może został "złamana" w przypadku gdy na danym dystansie mamy grupę, która osiągnęła limit zawodników i kolejną grupę która ma jednego zawodnika. Takie rzeczy się zdarzały i robiło się wtedy tak, że puszczało się jednego zawodnika z grupą wcześniejszą i czas startu jego grupy pokrywał się z czasem startu grupy poprzedniej,