Как избежать объекта GodManager GameManager?

Я просто прочитал ответ на вопрос о структурировании игрового кода . Это заставило меня задуматься о вездесущем классе GameManager и о том, как часто это становится проблемой в производственной среде. Позвольте мне описать это.

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

Затем есть зеленый свет, и, пытаясь очистить вещи, кто-то пишет GameManager. Вероятно, чтобы держать кучу GameStates, возможно, для хранения нескольких GameObjects, ничего неважно, действительно. Милый, маленький, менеджер.

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

Затем начинается производство, и вскоре, конечно, время хруста. Сбалансированная диета давно ушла, трекер трещины взламывает проблемы, люди стесняются, и игра должна быть выпущена вчера.

В этот момент, как правило, GameManager представляет собой реальный большой беспорядок (чтобы оставаться вежливым).

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

Конечно, это классический анти-шаблон: объект божества . Это плохо, боль, чтобы слиться, боль для поддержания, боль, чтобы понять, боль, чтобы трансформироваться.

Что бы вы посоветовали предотвратить это?

ИЗМЕНИТЬ

Я знаю, что соблазнительно обвинять именование. Конечно, создание класса GameManager не является такой замечательной идеей. Но то же самое может произойти с чистым GameApplication или GameStateMachine или GameSystem, который в конечном итоге становится любимым каналом-лентой к концу проект. Независимо от названия, у вас есть этот класс где-то в вашем игровом коде, сейчас это всего лишь эмбрион: вы просто еще не знаете, каким монстром он станет. Поэтому я не ожидаю ответов «обвинять имена». Я хочу, чтобы это не позволяло это происходить, это кодирование и /или процесс, который может следовать команде, зная, что это произойдет в какой-то момент производства. Слишком плохо, чтобы выбросить, сказать, один месяц исправлений и последних минут, только потому, что все они теперь находятся в одном огромном неудержимом менеджере.

49 голосов | спросил Laurent Couvidou 16 AMpMon, 16 Apr 2012 04:21:31 +040021Monday 2012, 04:21:31

5 ответов


23
  

Тогда есть зеленый свет, и, пытаясь очистить вещи, кто-то пишет GameManager. Вероятно, чтобы держать кучу GameStates, возможно, чтобы хранить несколько GameObjects, на самом деле ничего хорошего. Милый, маленький, менеджер.

Знаешь, когда я читал это, у меня в голове не было никаких тревог. Объект с именем «GameManager» никогда не будет симпатичным или маленьким. И кто-то сделал это, чтобы очистить код? Как это выглядело раньше? ОК, шутки в сторону: имя класса должно быть четким указанием того, что делает класс, и это должно быть одно (aka: принцип единой ответственности ).

Кроме того, вы все равно можете получить такой объект, как GameManager, но, очевидно, он существует на очень высоком уровне, и он должен заниматься задачами высокого уровня. Ведение каталога игровых объектов? Может быть. Облегчение связи между игровыми объектами? Конечно. Вычисление столкновений между объектами? Нет! Именно поэтому имя Manager недооценивается - оно слишком широкое и позволяет много злоупотреблений под этим баннером.

Быстрое эмпирическое правило о размерах классов: если вы используете несколько сотен строк кода для каждого класса, что-то начинает идти не так. Не переусердствуя, что-то, скажем, 300 LOC - это запах кода для меня, и если вы собираетесь за 1000, предупреждающие колокола должны уходить. Полагая, что почему-то 1000 строк кода проще понять, чем 4 хорошо структурированных класса по 250 каждый, вы обманываете себя.

  

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

Я думаю, что это так, потому что проблема разрешена для распространения до такой степени, что все становится полным беспорядком. Практика рефакторинг - это то, что вы ищете - вам нужно постоянно улучшать дизайн кода с малым шагом .

  

Что бы вы посоветовали предотвратить это?

Проблема не технологическая, поэтому вы не должны искать для нее технологических исправлений. Проблема в том, что в вашей команде существует тенденция создавать монолитные фрагменты кода и убеждение, что в среднесрочной или долгосрочной перспективе это будет работать так. Также кажется, что команде не хватает сильного архитектурного лидерства, который будет управлять архитектурой игры (или, по крайней мере, этот человек слишком занят, чтобы выполнить эту задачу). В принципе, единственный выход состоит в том, чтобы члены команды признали, что это мышление неверно. Это никому не способствует. Качество продукта будет ухудшаться, и команда будет тратить еще больше ночей на фиксацию вещей.

Хорошей новостью является то, что непосредственные ощутимые преимущества написания чистого кода настолько велики, что почти все разработчики очень быстро реализуют свои преимущества. Убедите команду работать таким образом на какое-то время, результаты останутся.

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

Изменить - Немного больше информации:

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

В частности, для разработки игры, принятый ответ этот вопрос в StackOverflow относительно советов «особенно игровой архитектуры»:

  

Следуйте Твердые принципы объектно-ориентированного проектирования ....

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

  • Исправьте вещи в тот же день, когда вы их закодируете.
  • Вы будете рады, что сделали это в течение нескольких часов.

На самом деле полагать, что это сложно; Мне удалось сделать это для моей собственной работы только потому, что я снова и снова испытывал эффекты. Несмотря на это, мне все еще сложно оправдать исправление кода, когда я мог бы еще больше размахивать ... Поэтому я определенно понимаю, откуда вы. К сожалению, этот совет, возможно, слишком общий и нелегкий. Однако я твердо верю в это! :)

Чтобы ответить на ваш конкретный пример:

Дядя Боб Clean Code делает удивительную работу по обобщению кода хорошего качества как. Я согласен с почти всем его содержанием. Итак, когда я думаю о вашем примере из 30 000 менеджеров LOC, я не могу согласиться с «хорошей причиной». Я не хочу звучать оскорбительно, но думать, что это приведет к этой проблеме. Нет никакой веской причины иметь такой код в одном файле - это почти 1000 страниц текста! Любое преимущество локальности (скорость выполнения или простота дизайна) сразу же будет аннулировано разработчиками, которые полностью увязли, пытаясь ориентироваться в этом чудовище, и это еще до того, как мы обсудим слияние и т. Д.

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

ответил Daniel B 16 PMpMon, 16 Apr 2012 17:01:21 +040001Monday 2012, 17:01:21
7

Это не проблема программирования игр, но с программированием в целом.

  

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

Вот почему вы должны нахмуриться на любом объектно-ориентированном кодере, который предложит классы с «Менеджером» в названии. Справедливости ради, я думаю, что практически невозможно избежать «полугодовых» объектов в игре, но мы просто называем их «системой».

Любое программное обеспечение имеет тенденцию загрязняться, когда крайний срок близок. Это часть работы. И нет ничего неправильного в « программировании каналов» , особенно когда вы должны отправить свой продукт через несколько часов. Вы не можете полностью избавиться от этой проблемы, вы можете просто уменьшить ее.

Хотя очевидно, что если вы соблазняетесь поместить вещи в GameManager, это означает, что у вас нет очень здоровой базы кода. Возможны две проблемы:

  • Ваш код слишком сложный. Слишком много шаблонов, преждевременная оптимизация, никто больше не понимает поток. Попытайтесь использовать больше TDD при разработке, если сможете, потому что это очень хорошее решение для борьбы со сложностью.

  • Ваш код плохо структурирован. Вы (ab) используете переменную globals, классы не связаны свободно, нет интерфейса вообще, нет системы событий и т. Д.

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

Наконец, это может быть проблема управления командой: было ли достаточно времени? Все знали об архитектуре, в которой вы собираетесь? Кто, черт возьми, допустил совершение с классом со словом «Менеджер» в нем?

ответил Raveline 16 AMpMon, 16 Apr 2012 11:23:05 +040023Monday 2012, 11:23:05
5

Итак, приведя одно возможное решение из более Enterprise-y world: проверили ли вы инверсию инъекции управления /зависимости?

В принципе, вы получаете эту инфраструктуру , которая является контейнером для всего остального в вашей игре. Он, и только он, знает, как подключить все вместе и какие отношения между вашими объектами. Ни один из ваших объектов не создает ничего внутри своих собственных конструкторов. Вместо того, чтобы создавать то, что им нужно, они спрашивают , что им нужно из рамок IoC; после создания IoC-структура «знает», какой объект необходим для удовлетворения зависимостей и заполняет его. Свободная связь FTW.

Когда ваш класс EnemyTreasure запрашивает контейнер для объекта GameLevel, фреймворк знает, какой экземпляр его дает. Как это знать? Может быть, он создавал это раньше, возможно, он задает некоторые близлежащие GameLevelFactory. Дело в том, что EnemyTreasure не знает, откуда пришел экземпляр GameLevel. Он знает только, что его зависимость теперь удовлетворена, и она может продолжать свою жизнь.

О, я вижу, что ваш класс PlayerSprite реализует IUpdateable. Хорошо, это здорово, потому что фреймворк автоматически подписывает каждый объект IUpdateable на Timer, где находится основной игровой цикл. Каждый таймер :: tick () автоматически вызывает все методы IUpdatedable :: update (). Легко, правильно?

Реально, вам не нужна эта платформа bighugeohmygod, чтобы сделать это для вас: вы можете сами сделать важные бит. Дело в том, что если вы обнаружите, что создаете объекты типа «Manager», то, скорее всего, вы не правильно распределяете свои обязанности среди своих классов или где-то не хватает некоторых классов.

ответил D. Hayes 16 AMpMon, 16 Apr 2012 08:10:22 +040010Monday 2012, 08:10:22
3

Раньше я обычно заканчивал класс богов, если я делаю следующее:

  • сядьте в редактор игры /IDE /блокнот, прежде чем я выписал диаграмму классов (или просто эскиз основных объектов)
  • Начните с очень смутного представления об игре и сразу же ее код, а затем начните итерацию по новым идеям, когда они придут.
  • создайте файл класса, называемый GameManager, когда я не создаю игру на основе состояния, подобную стратегии, основанной на поворотах, где GameManager фактически является объектом домена.
  • не заботятся о организации кода на ранней стадии

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

ответил brandon 16 PMpMon, 16 Apr 2012 17:41:40 +040041Monday 2012, 17:41:40
1

Я знаю, что этот вопрос сейчас старый, но я думал, что добавлю свои 2 цента.

При разработке игр у меня почти всегда есть объект Game. Тем не менее, это очень высокий уровень и на самом деле не делает «ничего».

Например, он сообщает классу Graphics Render, но не имеет ничего общего с процессом рендеринга. Он может попросить LevelManager загрузить новый уровень, но не имеет ничего общего с процессом загрузки.

Короче говоря, я использую полубожественный объект для организации использования других классов.

ответил OMGtechy 8 J000000Monday13 2013, 15:23:45

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132