Zamodelowanie meczu szachowego

0

Cześć, zastanawiam się jak najlepiej zamodelować mecz szachowy i operacje zapisywania wyniku oraz rankingu.

Najprostsze rozwiązanie jakie przychodzi mi do głowy:

  1. Wysyłam z frontu id meczu, id wygranego gracza i id przegranego, pobieram po id z bazy mecz, pobieram userów po id, przeliczam ich nowe rankingi i zapisuje te 3 obiekty (2 userów i ukończony mecz).

Nie podoba mi się to, że zapisuję 3 obiekty na raz ..

Myślałem też nad takim rozwiązaniem, że w encji User nie trzymam w ogóle czegoś takiego jak ranking, tylko zapisuje w Meczu po prostu, który z nich wygrał i o ile zmienił się ranking (bo wg rankingu ELO obu zmienia się tak samo). A sam ranking usera liczę sobie poprzez agregowanie wszystkich meczów, w których brał udział oraz startowego rankingu.

Jakieś opinie ?

0

No to jest całkiem fajne ćwiczenie na modelowanie. Ranking gracza może znajdować się w innym agregacie niż sam Gracz czy Mecz. Może być naliczany asynchronicznie po zakończeniu Meczu (np. w formie event sourcingu). Na szybko nie widzę powodu, aby któryś agregat zawierał w sobie inny, czyli można się odnosić po idkach (Mecz ma idki Graczy, Ranking ma id Gracza) co daje pożądaną niezależność i modularyzację. Jeśli chcesz wyświetlić ranking gracza, to jest to projekcja z agregatu Ranking.

0

@Charles_Ray:
Nie czuję za bardzo tego, żeby Ranking był osobnym agregatem. To bardziej dla mnie ValueObject w meczu. I może nie ranking tylko RankingDifference czy coś takiego. Ten Ranking z id gracza wydaje mi się taki sztuczny.

Chociaż kurde ... może faktycznie trzymać agregat rankingz id gracza, który będzie snapshotowany asynchronicznie jakimś cronem ..
Agregat kojarzy mi się z czymś większym co ma reguły biznesowe też .. No rozkmina leci :D

0

Jeśli tak zrobisz, to spinasz ranking z meczem, wiec tylko w ten sposób możesz zmieniać ranking, a po drugie będziesz musiał przeliczać go z meczy, zamiast trzymać z boku i odczytywać. Czy Mecz musi wiedzieć, że istnieje w ogóle Ranking? Warto jednak zewaluować parę modeli i wybrać na dana chwile optymalny, ale rozszerzalny.

0

@Charles_Ray:
Teraz mam tak, że rankingu nigdzie nie trzymam tylko przeliczam. No i to średnio optymalne.

Z drugiej strony jednak, trzymanie rankingu w jakimś profilu gracza to wg Ciebie dobra opcja ? Wtedy przy zakonczonym meczu muszę zapisywać 3 agregaty : 2 graczy z nowym rankigiem i ukończony mecz...

I jeszcze jedno pytanie: czy jeśli mam agregat z danymi gracza jak mail, nazwa itd i jak chcę zrobić agregat Rankingu z relacją 1-1 to id Rankingu to będzie id gracza czy jako osobne pola ?

0

Za bardzo myślisz widokiem i próbujesz go przełożyć 1-1 na tabelki zamiast skupić się na logice. Przecież nawet gdyby ranking był trzymany osobno, zawsze możesz pobrać ranking gracza po userId lub zrobić zapytanie z joinem. Jeżeli zamodelujesz ranking jako counter, to np. nie będziesz miał możliwości wyświetlenia kolejnych zmian rankingu np. razem z powodem zmiany (przegrana, wygrana, brak aktywności w grze itp)

0

No właśnie o to chodzi, że starałem się nie myśleć widokiem i zamodelowałem tak, że w agregacie meczu trzymam zaktualizowany ranking obu userów przez co, żeby odczytać ranking usera muszę wyciągnąć najnowszy mecz i odczytać stąd. Ale no takie odczytywanie z meczy jest chyba średnio optymalne.

I jeśli zamodelowałbym Ranking jako osobny agregat to wtedy przy zapisie takiego meczu muszę zapisać 3 agregaty : 2x Ranking + 1x Mecz. Czy uważasz, że to dobra praktyka ? DDD Mówi o zapisie 1 agregatu.

1

DDD radzi zapisywać jeden agregat w jednej transakcji. Asynchronicznie możesz wywołać tyle innych komend ile tylko potrzebujesz.

Brandolini mówił, ze w praktyce bardzo rzadko modelujemy zbyt wiele agregatów, wiec ja bym spróbował przećwiczyć model oparty o 3 agregaty.

0

Myślałem o wyemitowaniu eventu, że mecz się zakończył i obsłużeniu reszty asynchronicznie, ale w zapisie meczu wydaje mi się, że wszystko musi być zrobione od razu. Bo jeśli np zapiszę synchronicznie mecz, wyemituje event po to, żeby zupdatować oba rankingi i w międzyczasie dany gracz znowu z kimś wygra to będzie operował na starym rankingu ..

0

Pytanie stricte biznesowe: czy to problem?

0

Generalnie problemem nie jest nawet to, że zapisze ranking jednego usera a drugiego nie :D W konteście działania całej apki nikt tego nie zauważy (nie robię apki z szachami - to była tylko analogia).

Zamodelowałem ranking jako osobny agregat i trzymam w nim aktualną wartość, historię zmian wraz z datą oraz typ rankingu (bo doszedłem do tego, że mogę wprowadzić różne kategorie i każdy user będzie miał kilka rankingów).

A jeszcze pytanie co do samej obsługi asynchronicznych eventów. Nie robiłem tego jeszcze nigdy. Rozumiem, że emituję event domenowy i jakimś globalnym brokerem to przechwytuję tak ? Do tego się jakiejś Kaffki używa ?

1

Rozwiązań do messagingu jest wiele - Rabbit, Kafka, Redis, ...

1 użytkowników online, w tym zalogowanych: 0, gości: 1