Хороший стиль программирования при обработке нескольких объектов

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

Сначала я передавал соответствующие объекты методам, как их назвали, но это становилось очень утомительным, особенно когда методы потребовали многих объектов выполнить их задачи. Для решения этого я создал класс, который инициализирует и хранит все объекты, в которых я нуждаюсь. Это позволяет мне получать доступ к объекту от любого класса путем вызова Assets.dice (), например.

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

10
задан Skrud 23 April 2010 в 18:52
поделиться

5 ответов

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

Я думаю, что лучше создать «Контекст», содержащий текущие игральные кости, части и т.д., и передавать контекст по мере необходимости методам / классам, которые должны его использовать. Это намного чище, хотя да, это больно, когда приходится проходить его повсюду. Но вы получаете то преимущество, что вы можете отслеживать, кто и когда обращается к контексту, а также можете создавать фиктивные контексты для целей тестирования. Если вы передаете контекст высокоуровневому объекту, а он должен передать его своим подкомпонентам, вы от начала до конца знаете, что это за контекст и откуда он.

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

7
ответ дан 4 December 2019 в 01:56
поделиться

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

Так, например, однажды во время тестирования вашего приложения вы могли заметить, что ваш объект игральных костей ведет себя странно. Вы вызываете dice.roll () и иногда видите, что он возвращает 1. Но в данном случае это невозможно, потому что ваш игрок бросает два из них. Вы отлаживаете и каким-то образом замечаете, что свойство numberOfDice в какой-то момент изменилось на 1. С помощью такого метода контекста, как ваш, будет непросто найти, кто изменил numberOfDice на 1, потому что у всех есть доступ к играм в кости через ваш объект контекста. Вы уловили суть?

Так каково же решение? Одна из метафор, которая мне нравится в объектно-ориентированном программировании - разделяй и властвуй. Вам нужно найти поведения, процессы, объекты, которые можно изолировать друг от друга. Вам нужно разделить вашу проблему на управляемые части, которые можно изолировать от всего остального, что происходит в вашем приложении.

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

0
ответ дан 4 December 2019 в 01:56
поделиться

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

Одно из указаний, которое помогло мне разобраться в этом вопросе, - это диалог между двумя антропоморфными классами (если кто-то знает первоисточник этой цитаты, я был бы признателен за ссылку!):

Класс A говорит классу B: " Дайте мне значение x ».

Класс B:« Зачем вам нужно значение x? »

Класс A:« Чтобы я мог его фланцевать »

Класс B:« Спросите меня, и Я сделаю это для вас ».

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

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

Если вы хотите получить хорошее представление о шаблонах проектирования, я бы порекомендовал взять отличную книгу Head First Design Patterns .

2
ответ дан 4 December 2019 в 01:56
поделиться

Действительно ли это класс «бога» или просто «контекст», который является «контейнером» для всех этих взаимосвязанных экземпляров объектов одной игры, которые затем передаются в вызовы разных методов (так что у вас есть только один аргумент)? Последнее довольно распространено, и я не вижу в этом ничего плохого, но в этом случае сам контейнер не имеет реальной функциональности.

0
ответ дан 4 December 2019 в 01:56
поделиться

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

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

0
ответ дан 4 December 2019 в 01:56
поделиться
Другие вопросы по тегам:

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