Czy projektowanie oparte na domenie jest dobre dla gier?

10

Właśnie przeczytałem o modelach domen i to mnie oświeciło, odkąd opracowuję grę, która ma klasę, która przechowuje tylko dane (kilka zachowań / metod). Powierzyłem zadanie zarządzania tymi klasami menedżerom ... a teraz mój menedżer wydaje się być obiektem Boga. Mój obiekt gry, który powinien zajmować się logiką, jest po prostu anemicznym modelem domeny.

Mój obecny wzorzec projektowy jest w Singleton i chcę trochę przekodować, aby wydostać się z tego. Nigdy nie widziałem DDD w grach (na razie), ale czy to dobre podejście? Jestem tylko początkującym programistą (skłaniającym się ku grze), dlatego chcę dowiedzieć się więcej o dobrej architekturze, zanim gra stanie się zbyt rozdęta do przeprojektowania.

Sylpheed
źródło
2
Mogę powiedzieć, że popularnym projektem gier jest architektura Component. Nowy projekt, który zyskuje trochę na popularności w silnikach gier, to projektowanie zorientowane na dane (oznacza to tylko, że sposób umieszczenia danych w pamięci jest największym problemem projektowym). Ale nie mogę rozmawiać z Domain Driven Design w grach wideo .. więc stąd tylko komentarz.
James,
Gry nie są aplikacjami biznesowymi. Architektura dźwięku w aplikacji biznesowej (DDD / CQRS) zdecydowanie nie jest dźwiękiem w grze i odwrotnie. Dlaczego nie zbadać modelu dekoratora lub modelu komponentu? Są „dobre” do gier i złagodzą twój problem z singletonem - nawet mówiąc, że singletony są zazwyczaj w porządku; szczególnie jeśli robisz rozwój niezależny. Skoncentruj się na ukończeniu czegoś, inaczej wylądujesz jak ja ze świetną architekturą, ale bez gry.
Jonathan Dickinson
Dzieki za sugestie. Przeczytam o projekcie komponentu. Skończę grę, nad którą pracuję, choć jej wygląd nie jest tak dobry. Mam termin w listopadzie, lol. Usunąłem koncepcję Singleton i wstrzykuję moduły do ​​obiektów, które tego potrzebują. Myślę, że na razie to wystarczy, ale muszę się dowiedzieć więcej.
Sylpheed,

Odpowiedzi:

12

Nigdy nie słyszałem o projektach opartych na domenach przed Twoim postem. Szybkie spojrzenie na kilka odniesień - tu i tutaj - wydaje się sugerować, że jest to tylko fantazyjna nazwa tradycyjnej metody programowania obiektowego z lat 90., której nauczono mnie na uniwersytecie, gdzie próbujesz pisać zajęcia dla każdego pojawiającego się rzeczownika w sytuacji, w której próbujesz modelować za pomocą oprogramowania, aby struktura oprogramowania zdawała się odpowiadać strukturze rzeczywistej koncepcji.

Jako taka, moja odpowiedź na to jest taka, że ​​to nie jest „dobre”. Zazwyczaj jest to rozsądny punkt wyjścia, ale okazuje się, że nie jest on odpowiedni w miarę postępów. Rzadko masz jedną domenę, ale kilka różnych domen w ramach jednego oprogramowania - na przykład możesz mieć domenę gry (świat, postacie, przedmioty), domenę renderera (shadery, siatki, materiały), dziedzina danych wejściowych (system plików, sieć, klawiatura i mysz) oraz problemy pojawiają się, gdy domeny nakładają się i wpływają na siebie nawzajem. Często podczas łączenia dwóch domen zdajesz sobie sprawę, że istnieje tam zależność, która wymaga zmiany, co oznacza, że ​​jedna z twoich reprezentacji staje się bardziej obciążeniem niż pomocą.

Niejasnym przykładem może być biblioteka matematyczna na konsoli i twoje postacie w grze. Twoja biblioteka matematyczna będzie chciała mieć dużą listę danych, a następnie 1 instrukcję do wykonania na tej liście, aby działać wydajnie. Każda z twoich postaci w grze będzie miała własny zestaw danych wierzchołków do renderowania i animacji itp. A teraz, jak uzyskać długą listę wszystkich danych wierzchołków od każdej z twoich postaci, aby móc obsłużyć je za jednym razem? Możesz wykonać powolną operację kopiowania lub zamiast tego możesz refaktoryzować swoje postacie, aby ich dane były bardziej podatne na przetwarzanie przez bibliotekę matematyczną - ale wtedy jedna z twoich domen rozpada się na korzyść innej.

Osobiście jestem bardzo ostrożny w stosunku do jakiejkolwiek etykiety, która przypomina „Projekt oparty na czymkolwiek”. Oprogramowanie jest zarówno zbyt rozległe, jak i zbyt złożone, aby stworzyć uniwersalne podejście do jego tworzenia. Zamiast tego, próbując napisać najlepsze oprogramowanie, jakie potrafię, staram się powrócić do zasad SOLID . Dają ci dobry obraz tego, jak dobry jest twój kod, bez obiecywania panaceum na metodę, którą możesz zastosować i magicznie osiągnąć dobry kod. Niestety, bez takiej załączonej metodologii, zanim nauczysz się, jak stosować się do tych wytycznych, potrzeba dużo doświadczenia, prawdopodobnie dlatego tak wielu ludzi lubi metodyki.

Jeśli chodzi o problem posiadania klas anemicznych i obiektów menedżera, jest to zwykle coś, co zostało omówione we wstępnych lekcjach orientacji obiektu i tak naprawdę nie wymaga zastosowania żadnej specjalnej metodologii, aby to „naprawić”. (Możesz zacząć od książki o programowaniu obiektowym, jeśli dopiero zaczynasz.) Klasa jest sprzężeniem stanu i zachowania, gdzie zachowanie modyfikuje ten stan, i nazywa się to enkapsulacją. Zasadniczo próbujesz hermetyzować jak najwięcej, co oznacza, że ​​stanem powinien manipulować sam obiekt (i tylko ten obiekt). Tylko w przypadku zachowania, którego nie można modelować w klasie, można delegować do klasy zewnętrznej, takiej jak menedżer, dlatego też istnienie klas menedżerów jest często uważane za oznakę źle napisanego kodu obiektowego.

Mój obecny wzorzec projektowy jest w Singleton i chcę trochę przekodować, aby wydostać się z tego.

Nie wiem, co masz na myśli przez ten wiersz. Wzorzec projektowy jest dobrze znanym sposobem pisania małej części twojego programu. Nie miałbyś „aktualnego” wzorca projektowego, ani nie ukształtowałby reszty twojego programu. Dla początkujących wzorce te są przydatne, aby pomóc ci znaleźć właściwą ścieżkę, podczas gdy dla ekspertów są one bardziej sposobem na komunikowanie się na temat typowych sytuacji w kodzie. Jedna rzecz jest jednak ważna: singletony są prawie zawsze złym pomysłem i należy ich unikać, gdy tylko jest to możliwe. Możesz znaleźć wiele opinii na temat singletonów na tej stronie i na stronie Stack Overflow, ale oto jedno praktyczne pytanie z odpowiedziami, które pomogą ci uniknąć ich potrzeby.

Kylotan
źródło
Dobra, pozwól mi trochę zmienić pytanie. Czy istnieje różnica między modelami domen a projektami opartymi na domenach? Moim pomysłem na modele domen jest to, że klasa powinna być w stanie sobie poradzić bez polegania na kontrolerze / menedżerze w jak największym stopniu. Mój obecny projekt pokonuje ten cel. Mogę coś źle zrozumieć. Tak więc w grze RPG moja klasa graczy ma swoją własną domenę i składa się z różnych domen, takich jak umiejętności, przedmioty itp.
Sylpheed
Tak, klasa powinna być w stanie sama sobie poradzić bez polegania na kontrolerze / menedżerze w jak największym stopniu, ale nie ma to nic wspólnego z modelami domen i jest tylko standardowym podejściem do programowania obiektowego. Nie jest jasne, co może być nieporozumieniem, ponieważ nie wiem, dlaczego masz takie klasy menedżerskie.
Kylotan 10.10.11
Nie widzę, jak sprawić, by mój moduł działał bez menedżera lub klasy, która odpytywałaby mój obiekt. Na przykład mam moduł do zadań. Aby uzyskać dostęp do właściwego zadania, muszę zapytać kierownika. Jak więc przejść przez to bez menedżera?
Sylpheed,
Co to jest „właściwe” zadanie? Skąd menedżer wie, co jest właściwe? Domyślam się, że logika, która podejmuje takie decyzje, opiera się na innych obiektach, aby je wykonać, a te inne obiekty są lepszymi kandydatami na tę funkcjonalność.
Kylotan
Cóż, teraz mój menedżer działa jak repozytorium po pewnym czyszczeniu. Na przykład mam 10 zadań na żywo. Uzyskuję dostęp do tych zadań za pomocą identyfikatora, aby łatwiej je odzyskać. Więc mój gracz ma komponent do zadań (menadżer) i stamtąd uzyskam dostęp do zadania. Nadal gracz kontroluje, jakie zadanie może mieć. Czy to zły pomysł?
Sylpheed,
6

Paradygmat

W chwili, gdy ta odpowiedź została napisana, wszystkie pozostałe opublikowane tutaj odpowiedzi są błędne.

Zamiast pytać, czy projektowanie oparte na domenie jest dobre dla gier. Powinieneś zapytać, czy „Modelowanie domen” jest dobre dla gier.

Czy modelowanie domen jest dobre dla gier?

Odpowiedź brzmi: czasami jest to absolutnie fantastyczne. Jeśli jednak tworzysz grę w czasie rzeczywistym, taką jak platformówka, FPS lub cokolwiek innego (WIELE WIELU rodzajów gier), to nie. Niekoniecznie nadaje się do tych systemów. Mogą jednak istnieć systemy w obrębie tych gier, w których skuteczne jest wdrożenie wzorca modelu domeny.

Jak wspomnieli tu inni, szkielety elementów-bytów są bardzo popularne i nie bez powodu. Jednak w kulturze tworzenia gier wydaje się wyraźny brak architektur warstwowych. Ponownie, jest to słuszny powód, ponieważ większość gier, które ludzie będą rozwijać, po prostu mutuje stan na bytach i niech powstające konsekwencje będą grą.

CAŁE OPROGRAMOWANIE NIE JEST OPROGRAMOWANIEM, KTÓRE JESTEŚ PISEMY. Niektóre różnią się od innych.

Niektóre przykłady domen, w których modelowanie domen działa dobrze, to gry karciane, planszowe i inne typy systemów sterowanych zdarzeniami.

Gry, które działają z częstotliwością klatek na sekundę z ruchem itp., Określone przez delty czasowe, ponieważ podstawowe koncepcje domenowe prawdopodobnie nie są świetne. W takim przypadku nasza „domena” jest często tak prosta, że ​​nie ma potrzeby modelowania domen. Wykrywanie kolizji, odradzanie się nowych bytów, wpływ sił na istniejące byty itp. Zwykle obejmują większość rozgrywki.

Jednak, gdy sprawy stają się skomplikowane, zaczyna się widzieć, jak programiści wdrażają modele domen w swoich jednostkach, aby obsłużyć określone typy zachowań i obliczeń.

Wzorzec modelu domeny w architekturze gry

Silnik gry (na przykład Unity3D) jest często zorientowany na elementy składowe. W platformówce możesz mieć byt dla swojej postaci, a jego stan jest ciągle zmieniany w celu aktualizacji pozycji itp.

Jednak w grze opartej na zdarzeniach bardziej prawdopodobne jest, że rola struktury komponent-byt raczej po prostu istnieje jako interfejs użytkownika. W efekcie powstaje architektura warstwowa.

Interfejs użytkownika renderuje stan gry dla użytkownika. Użytkownik wchodzi w interakcję z interfejsem użytkownika, wyzwalając polecenia w warstwie usługi. Warstwa usługi współdziała z obiektami domeny. Obiekty domeny wywołały zdarzenia domeny. Detektory zdarzeń słyszą zdarzenia i wyzwalają zmiany w interfejsie użytkownika.

Interfejs użytkownika> Warstwa usługi> Model domeny

Krótko mówiąc, skończyć z kontrolerem widoku modelu z implementacją warstwy usług.

Korzystając z tej architektury, masz w pełni testowalny rdzeń gry (rzadkość w kulturze tworzenia gier, i to pokazuje) z interfejsem sterowanym zdarzeniami.

Ok teraz, co to jest DDD?

Projektowanie oparte na domenie to w szczególności kultura / ruch kładący nacisk na wzorce analityczne, które są wykorzystywane do zdobywania wiedzy o domenie, dzięki czemu właściwie budujesz właściwą rzecz, a następnie wzorce implementacyjne, które upoważniają do wdrożenia warstwy modelu reprezentującej koncepcje w modelu domeny przy użyciu idiomu języka. DDD wywodzi się ze społeczności, która pracuje ze skomplikowanymi domenami i zawsze szuka sposobów zarządzania wysoką złożonością swoich aplikacji, koncentrując się na modelowaniu domen.

DDD nie radzi sobie tak dobrze, jeśli Twoim celem jest po prostu zacząć kodować, bawić się systemem, a następnie dowiedzieć się, co chcesz zbudować później itp. Zakłada się, że istnieje mniej więcej domena. Więc jeśli nie masz pojęcia, jaka będzie Twoja gra ... To nie zadziała.

Shawn McCool
źródło
1
Dzięki za wgląd. Wymyśliłem to może 3 lub 4 lata temu. Byłem wtedy naiwny (5 lat temu), ponieważ zawsze staram się dopasować „wzorzec projektowy” do wszystkich moich problemów. Nauka tych „wzorów” i architektury pomogła, ponieważ dała mi więcej opcji. Zawsze trzymam się abstrakcji części mojego kodu „wystarczająco”, aby było to łatwe dla projektantów (bardzo ważne), testów jednostkowych i przyszłej mechaniki. Przeładowanie architektury utrudniało pracę i nauczyłem się tego na własnej skórze. W tej chwili wykorzystałem już architekturę opartą na komponentach, aby dopasować się do mojego stylu kodowania. SOLID ftw.
Sylpheed
3

Nie, nie sądzę, aby DDD lub jakakolwiek inna architektura „modnego hasła” była naprawdę dobra dla gier. Z możliwym wyjątkiem „systemu komponentów”, który wydaje się tutaj bardzo popularny.

Kiedy słyszę takie pytania i dyskusje, przypominam sobie stronę. Zastanawianie się nad modnymi modami na temat architektury zwykle przyniesie ci mniej korzyści niż projektowanie i kodowanie własnej aplikacji.

Nieważne
źródło
1
+1 za „faktycznie projektowanie i kodowanie własnej aplikacji”. wzorce te są dla mnie wskazówkami i prowokującymi do myślenia - niczym więcej. Zmiana problemu tak, aby pasował do rozwiązania, jest niewłaściwa.
Jonathan Dickinson
-1

Tak, ale powinieneś się dostosować.

Korzystając z DDD zyskasz modułowość i pojedynczą odpowiedzialność za każdą domenę. Ale wszystko inne tylko komplikuje sprawę.

Zobacz moją odpowiedź tutaj

b.ben
źródło
Możesz nieco rozszerzyć swoją odpowiedź (omów główną część odpowiedzi), ponieważ w tej chwili jest to tylko odpowiedź na link (nawet jeśli wskazuje na inną stronę wymiany stosów).
Vaillancourt