Я работаю над маленькой игрой, написанной на Java (но вопрос - агностик). Поскольку я хотел исследовать различные шаблоны проектирования, я повесил на Composite pattern/Entity system (который я изначально читал о здесь и здесь) в качестве альтернативы типичному глубокому иерархическому наследованию.
Теперь, написав несколько тысяч строк кода, я немного смущен. Я думаю, что понимаю шаблон, и мне нравится его использовать. Я думаю, что это очень круто и Starbucks-ish, но он чувствует, что преимущество, которое он предоставляет, несколько недолговечно и (что раздражает меня больше всего), сильно зависит от вашей детализации.
Вот фотография из второй статьи выше:
Мне нравится, как объекты (игровые объекты или все, что вы хотите их назвать) имеют минимальный набор компонентов, и предполагаемая идея заключается в том, что вы можете написать код, который выглядит примерно так:
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());
.., что было бы очень приятно... но в REALITY код заканчивается тем, что выглядит как
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());
Кажется, что у меня есть некоторые очень специализированные компоненты, состоящие из меньших компонентов. Часто мне приходится составлять некоторые компоненты, которые имеют зависимости от других компонентов. В конце концов, как вы можете сделать, если у вас нет позиции? Не только это, но и то, как вы в конечном итоге оказываете игроку против инопланетянина против гранаты, может быть принципиально иным. У вас не может быть ОДНОГО компонента, который диктует все три, если только вы не делаете очень большой компонент (в этом случае... почему вы все равно используете составной шаблон?)
Чтобы привести другой пример в реальной жизни. У меня есть персонажи в моей игре, которые могут экипировать различные снаряды. Когда экипировка оснащена, некоторые статистические данные изменяются, а также визуально отображаются. Вот как выглядит мой код прямо сейчас:
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);
Приведенный выше CharacterAnimationRender.class
влияет только на то, что отображается VISUALLY. Поэтому мне явно нужно сделать еще один компонент, который обрабатывает статистику снаряжения. Однако зачем мне делать что-то вроде:
billy.addControllers(new CharacterStatistics());
billy.get(CharacterAnimationRender.class).setBody(BODY.NORMAL_BODY);
billy.get(CharacterStatistics.class).setBodyStats(BODY_STATS.NORMAL_BODY);
Когда я могу просто создать контроллер/компонент CharacterGearStuff
, который обрабатывает BOTH распределение статистики, а также визуальное изменение?
В нижней строке, я не уверен, как это должно помочь повысить производительность, поскольку, если вы не хотите обрабатывать все вручную, вам все равно придется создавать "мета-компоненты", которые зависят от компонентов 2+ (и изменять/перекрестно изменять все их подкомпоненты - возвращение нас в ООП). Или, может быть, я думаю об этом совершенно неправильно. Я?