Posted on 5 listopada, 2017
Lubię DDD
Na studiach nauczono mnie programować obiektowo, lecz w pracy ta umiejętność nie bardzo mi się przydała. Pierwszy duży projekt, z którym się w niej spotkałem, był napisany w architekturze trójwarstwowej. Musiałem zapomnieć o tym czego się wcześniej nauczyłem i zacząć pisać strukturalny kod jak w C tylko, że w Javie. Nie widziałem sensu pisania kodu w taki sposób. Miesiącami próbowałem zrozumieć dlaczego tak, a nie inaczej napisana jest aplikacja. Podczas analizy w mojej głowie pokazywały się rozwiązania obiektowe, które były łatwiejsze w zrozumieniu i krótsze niż serwisy opisane w 1000 linii, w których znajduje się wszystko.
Jestem po kilkudziesięciu wykładach i książce z „Czystego Kodu” („Czysty kod. Podręcznik dobrego programisty” – Robert C. Martin). Nie było to dla mnie nic odkrywczego, pomogło mi jednak w nazwaniu niektórych rzeczy, co ułatwia współpracę w zespole. Same zasady czystego kodu nie pokazują jak pisać kod obiektowo. Tu z odsieczą przyszli Vaughn Vernon i Eric Evans („Implementing Domain Drive Design”, „Domain-Driven Design: Tackling Complexity in the Heart of Software”), którzy pokazali jak to robić oraz jak to robić z biznesem.
Zgodnie z zasadą czystego kodu wszystko co zostanie napisane musi zostać przetestowane. W Unity3D stosuje się obiekty MonoBehaviour, w których znajduje się większość logiki. Przez długi okres czasu obiekty te były „nietestowalne”. Twórcy Unity chcąc pomóc programistom zaczęli tworzyć tutoriale jak rozdzielać obiekty tak aby choć po części dało się je przetestować.
Moim zdaniem nie wygląda to za dobrze. Jak dla mnie MonoBehaviour powinny zajmować się tylko wyświetlaniem modelu albo zbieraniem danych od użytkownika. Cała reszta logiki gry powinna znajdować się gdzieś pod spodem. Ostatnio znalazłem przydatne narzędzie:
które umożliwia testy obiektów MonoBehaviour, z czego bardzo się ucieszyłem.
DDD skłoniło mnie do myślenia o tym jakich narzędzi brakuje mi w Unity. Dlatego zacząłem pisać framework „Dynamics”. W pierwszej wersji chciałbym aby projekt zawierał trzy rzeczy:
- obsługę rozkazów
- obsługę zdarzeń
- kontener z zależnościami
Pierwszą poboczną funkcjonalnością w Dynamics, którą będę potrzebował to planista. Będzie on wykorzystywany w CommandBus i EventBus. Dzięki IoC w łatwy sposób będę mógł podmienić jego implementacja z jednowątkowej na wielowątkową. Planista będzie kolejkował zdefiniowane przez inne obiekty akcje. Mógłbym skorzystać z .Net Reactive Extension lecz niestety nie działa w Unity3D. Ktoś już zauważył ten brak i stworzył implementację dla Unity3D. Nazwał ją UniRx. Nie skorzystam jednak z gotowego rozwiązania, aby zwiększyć swoją przyjemność z pisania. Kolejną funkcjonalnością do napisania po planiście będzie obsługa poleceń. Każda zmiana stanu gry rozpocznie się od rozkazu, który nazwą wskazuje na intencję, a we wnętrzu posiada dane do podjęcia akcji. Podczas pisania będę się wzorował na Axon Framework. Następnie napiszę obsługę zdarzeń, które wyrażają zmianę stanu gry.
Kod można znaleźć na GitHubie: Dynamics – I like ddd
Na repo nie było nic ciekawego, więc wraz z porzuceniem projektu usunąłem je.