Показать сообщение отдельно
Старый 26.06.2018, 16:07
RedHead90 вне форума Посмотреть профиль Отправить личное сообщение для RedHead90 Найти все сообщения от RedHead90
  № 7  
Ответить с цитированием
RedHead90

Регистрация: Apr 2018
Сообщений: 42
Appleman, Ну смотри. У тебя есть Character, который использует CharacterData. Да, это композиция, но...

В текущей реализации ты дублируешь все поля CharacterData в Character. Это значит, что изменяя CharacterData, тебе обязательно придется лезть в Character, повторяя все изменения также и в нем. Нарушается принцип черного ящика. Ты неизбежно будешь получать ошибки и добавишь себе кучу рутинной работы. Ты, конечно, можешь поручить рутину своей среде разработки, если она это умеет, используя интерфейсы или функцию делегирования методов, как, например в IntelliJ IDEA. Но даже это полностью не избавит тебя от рутины.

Чтобы избавить себя от рутины и кучи потенциальных ошибок, ты можешь сделать Character наследником CharacterData. Все изменения во втором автоматически будут менять и первый. Но тогда теряются все достоинства композиции.

Еще ты можешь сделать так, как я писал выше - добавить в Character всего один метод getData():CharacterData. Тогда, меняя CharacterData, ты не пустишь волну изменений в других классах, как в первом случае. Character знает о том, что у него есть характеристики, но о том, какие они, сколько их и как они работают - об этом ему ничего не известно.

Ну и четвертый вариант. Ты можешь реализовать все по шаблону ECS, как в Ash. Тогда у тебя вообще исчезнут такие классы, как Character, CharacterNPC, CharacterPlayer и т.д. в том виде, какие они сейчас. У тебя будут сущности, как контейнеры для всевозможных компонентов и будут узлы, которые определяют связки конкретных компонентов. Например, если сущность имеет такие компоненты, как CharacterData, Equipment, Inventory, Player, View, Position, то движок работает с ней, как с классом героя. Заменяем компонент Player на NPC, и это уже бот. Берем уже готовые компоненты Inventory, View, Position и добавляем ItemContainer, и эта сущность становится сундуком. Далее происходит магия. Все эти сущности имеют компоненты View и Position. Этих данных достаточно для того, чтобы поместить объект на игровую карту. Т.е. система, отвечающая за отображение объектов на карте может работать со всеми ими одинаково. И ей плевать, сундук это, дерево или NPC. Данные полностью отделяются от логики, зависимости между компонентами находятся не в самих компонентах, а выносятся на уровень выше. Раздутых классов нет, все лежит на своих местах и занимается одной определенной задачей. В общем это все долго можно расписывать, лучше погугли сам. Даже на этом сайте где-то были уроки по данному подходу.