Моделирование для большого количества объектов, связанных с другими объектами («иметь») - PullRequest
1 голос
/ 01 февраля 2012

Я пытаюсь действительно получить хорошее представление о том, как думать в терминах ООП, поэтому у меня в голове есть полус гипотетический сценарий, и я искал некоторые мысли.

Если бы я хотел разработать симуляцию для разных типов людей, взаимодействующих друг с другом, каждый из которых мог бы приобрести разные уровни мастерства в разных «навыках», каким был бы оптимальный способ сделать это?

Это действительно «навык», который меня немного увлек. Мои требования следующие:
-Каждый человек либо "имеет" навык, либо его нет
-Если у людей есть навыки, у них также есть «уровень квалификации», связанный с навыком.
-Мне нужен способ найти и выбрать каждого человека, который имеет определенные навыки вообще или на определенном уровне. -Дизайн должен быть расширяемым (т.е. мне нужно иметь возможность добавить больше «навыков» позже)

Я рассмотрел следующие варианты:

  1. есть гигантское перечисление для каждого включенного мной навыка, и пусть класс персонажа содержит Участник "int Skills [TOTAL_NUM_SKILLS]". Массив будет иметь нули для «неприобретенных» навыков и от 1 до (макс.) Для уровней владения «приобретенными навыками».

  2. имеют такое же гигантское перечисление, и класс персонажа содержит карту навыков (из перечисления) и числа, связанные с навыками, так что вы можете просто добавить только приобретенные навыки на карту и связать число таким образом.

  3. Создайте конкретный класс для каждого навыка, и каждый из них наследует от абстрактного базового класса (скажем, ISkill), и пусть у класса персонажа будет карта

Действительно, вариант 1 кажется простым и понятным способом сделать это. Пожалуйста, критикуйте; есть ли причина, по которой это не приемлемо? Есть ли более объектно-ориентированный способ сделать это?

Я знаю, что вариант 3 сейчас не имеет особого смысла, но если бы я решил расширить его позже, чтобы навыки были чем-то большим, чем просто умения, связанные с ними (т.е. фактически связывали новые действия с навыками (ISkill) :: DoAction и т. Д.), Имеет ли это смысл в качестве опции?

Извините за широкий вопрос, я просто хочу посмотреть, имеет ли смысл эта линия мышления, или я вообще лаю не на том дереве.

Ответы [ 2 ]

1 голос
/ 01 февраля 2012

Проблема с вариантом 1 - будущая совместимость.Скажем, вы отправляли эту платформу клиентам.Теперь клиент создал этот массив значений Skill, который составляет длину TOTAL_NUM_SKILLS для каждого человека.Но это терпит неудачу, как только вы пытаетесь добавить другой навык, и особенно когда вы пытаетесь изменить порядок навыков.

Что если клиент использует инфраструктуру RPC, в которой клиент и сервер передают Person объекты черезпровод?Теперь, если клиент не обновляет клиент и сервер в одно и то же время, RPC вызывает прерывание, поскольку теперь клиент и сервер ожидают массивы различной длины.Это может быть особенно сложно, потому что клиент может владеть только клиентом или только сервером и не может обновлять оба сразу.

Но это становится хуже.Скажем, клиент записал объект Person на диск в каком-то файле.Если они решили сериализовать человека в виде простого списка чисел, то новый навык приведет к сбою кода десериализации.Хуже того, если вы переупорядочиваете навыки в своем перечислении, код десериализации может работать просто отлично, но дает неправильный ответ.

Мне нравится вариант 3 именно по той причине, которую вы назвали: позже вы можете добавить больше функциональности и сделать этобезопасно (хорошо, за исключением того факта, что каждое публичное изменение является критическим изменением , если ваши клиенты использовали определенные крайние случаи на языке).

0 голосов
/ 01 февраля 2012

Если вы хотите часто добавлять навыки без изменения общей структуры программы, я бы рассмотрел какой-то внешний файл данных, который вы можете изменить, не перекомпилировав свой код.Подумайте, как бы вы хотели сделать это в действительно большом проекте.Человек, который выбирает навыки, может быть дизайнером без навыков программирования.Он мог редактировать навыки в файле XML, но не в коде C ++.

Если вы определили навыки в XML, это естественно расширится, чтобы хранить больше данных с каждым навыком.Ваши проигрыватели также могут быть сериализованы в виде файлов XML.

Когда вы настраиваете навыки игрока во время выполнения, вы можете создать хеш-таблицу, основанную на имени навыка из файла XML.Если чаще перечислять умения игрока, чем задавать вопрос, обладает ли игрок определенным умением, вы можете просто использовать вектор строк.

Конечно, это решение будет использовать больше памяти и работать медленнее, чем ваше перечислениерешение.Но, вероятно, этого будет достаточно, если вы не имеете дело с миллионами игроков в вашей программе.

...