Pracuję nad małą grą napisaną w Javie (ale pytanie jest agnostyczne). Ponieważ chciałem zbadać różne wzorce projektowe, zostałem zawieszony na systemie Composite pattern/Entity (który pierwotnie czytałem o here i here) jako alternatywie dla typowego dziedziczenia o głębokiej hierarchii.Złożony układ wzorca/podmiotu i tradycyjny OOP
Teraz, po napisaniu kilku tysięcy linii kodu, jestem nieco zdezorientowany. Myślę, że rozumiem ten wzór i lubię go używać. Myślę, że to bardzo fajne i Starbucks-owski, ale wydaje się, że korzyść, którą zapewnia, jest nieco krótkotrwała i (co mnie irytuje) w dużym stopniu zależna od twojej ziarnistości.
Oto obraz z drugiego artykułu powyżej:
Uwielbiam sposób obiekty (podmioty grze, czy jakkolwiek to nazwać) mają minimalny zestaw komponentów i wywnioskować, pomysł jest, że można napisać kod, który wygląda mniej więcej tak:
BaseEntity Alien = new BaseEntity();
BaseEntity Player = new BaseEntity();
Alien.addComponent(new Position(), new Movement(), new Render(), new Script(), new Target());
Player.addComponent(new Position(), new Movement(), new Render(), new Script(), new Physics());
.. co byłoby naprawdę miło ... ale w rzeczywistości, kod kończy się szuka czegoś takiego
BaseEntity Alien = new BaseEntity();
BaseEntity Player = new BaseEntity();
Alien.addComponent(new Position(), new AlienAIMovement(), new RenderAlien(), new ScriptAlien(), new Target());
Player.addComponent(new Position(), new KeyboardInputMovement(), new RenderPlayer(), new ScriptPlayer(), new PhysicsPlayer());
Wygląda na to, że mam kilka bardzo wyspecjalizowanych komponentów, które składają się z mniejszych komponentów. Często muszę tworzyć komponenty, które mają zależności z innymi komponentami. W końcu, jak możesz renderować, jeśli nie masz pozycji? Nie tylko to, ale sposób w jaki grasz przeciw obcemu kontra granat może być zasadniczo różny. Nie możesz mieć JEDNEGO komponentu, który dyktuje wszystkie trzy, chyba że stworzysz bardzo duży komponent (w takim przypadku ... dlaczego i tak używasz złożonego wzoru?)
Podaj kolejny przykład z życia wzięty. Mam w mojej grze postacie, które mogą wyposażyć różne przedmioty. Gdy sprzęt jest wyposażony, niektóre statystyki są zmieniane, a także wyświetlane na ekranie. Oto co mój kod wygląda teraz:
billy.addControllers(new Movement(), new Position(), new CharacterAnimationRender(), new KeyboardCharacterInput());
billy.get(CharacterAnimationRender.class).setBody(BODY.NORMAL_BODY);
billy.get(CharacterAnimationRender.class).setFace(FACE.BLUSH_FACE);
billy.get(CharacterAnimationRender.class).setHair(HAIR.RED_HAIR);
billy.get(CharacterAnimationRender.class).setDress(DRESS.DRAGON_PLATE_ARMOR);
Powyższy CharacterAnimationRender.class
wpływa tylko to, co wyświetlane wizualnie. Tak więc wyraźnie potrzebuję stworzyć kolejny komponent, który będzie obsługiwał statystyki biegów. Jednak dlaczego miałbym zrobić coś takiego:
billy.addControllers(new CharacterStatistics());
billy.get(CharacterAnimationRender.class).setBody(BODY.NORMAL_BODY);
billy.get(CharacterStatistics.class).setBodyStats(BODY_STATS.NORMAL_BODY);
Kiedy mogę po prostu zrobić CharacterGearStuff
kontrolera/komponent, który obsługuje zarówno dystrybucję statystykach, a także zmiany wizualne?
Podsumowując, nie jestem pewna, w jaki sposób ma to pomóc w zwiększaniu produktywności, ponieważ jeśli nie chcesz zajmować się wszystkim ręcznie, musisz nadal tworzyć "meta-komponenty", które zależą od 2 składników (i modyfikują/krzyżują zmodyfikuj wszystkie ich podkomponenty - przywracając nas do OOP). A może myślę o tym zupełnie nie tak. Czy ja jestem?
Cześć Adam, dziękuję za odpowiedź na to pytanie: D - właściwie podzieliłem dane i logikę mojego kodu (tak jak wspominasz na swoim blogu). W rzeczywistości, 'Position()', 'Movement()', itp. To to, co nazywam kontrolerami, które "zależą" od modeli danych (które można nazwać komponentami, jak sądzę, które są prostymi klasami, które składają się TYLKO z prywatnych elementy danych (w przypadku pozycji, 'private double x;' i 'private double y;') - wszystkie te powiązania wykonuję wewnętrznie dla kontrolerów. –