OO по сравнению с Простотой когда дело доходит до взаимодействия с пользователем

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

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

  1. Давая каждому пространству его собственный объект, все подклассы объекта Пространства, таким образом, взаимодействие может быть определено самим объектом пространства. Я мог сделать это путем реализации другой земли () методы для каждого типа пространства.

  2. Только давая Свойства и Утилиты (поскольку каждое свойство имеет уникальные функции), объекты и методы создания для контакта с покупкой/арендой и т.д. в основном классе программы (или Совет, как я называю его). Пробелам нравится, идут, и супер налог мог быть реализован маленьким набором условной проверки, чтобы видеть, находится ли плеер на специальном пространстве.

Опцией 1 является, очевидно, OO (и я чувствую корректное), способ сделать вещи, но я хотел бы только должным быть обработать взаимодействие с пользователем из программ основной класс. Другими словами, я не хочу объекты пространства взаимодействовать с плеером. Почему? Errr. Большое кодирование, которое я сделал к настоящему времени, имело эту простоту, но я не уверен, является ли это несбыточной мечтой или не для больших проектов. Я должен действительно обрабатывать взаимодействие с пользователем в совершенно отдельном классе?

Поскольку Вы видите, что я вполне смущен этой ситуацией. Есть ли некоторый окольный путь это? И, у кого-либо есть совет относительно практического дизайна OO, который мог помочь в целом?

Править: Точно так же, как, чтобы отметить, что я чувствую, что потерял немного внимания на этот вопрос. Я интересуюсь общей методологией объединения OO и любого внешнего действия (командная строка, сети, GUI, управление файлами и т.д.) действительно.

9
задан Bill the Lizard 16 September 2012 в 22:33
поделиться

7 ответов

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

Тем не менее, вы должны тщательно продумать, что каждый субъект в системе должен знать об остальном. Должно ли свойство действительно знать об игроке, балансе его счета и других игроках? Возможно нет. Недвижимость должна знать, сколько она стоит, сколько стоит ее рента и т. Д.

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

Задумайтесь на мгновение о приземлении на квадрат. После приземления у игрока есть 3 варианта:

  • Купить собственность
  • Игнорировать собственность
  • Оплатить аренду

Теперь, какой игрок в системе знает всю информацию, необходимую для этого. У нас есть класс Game, который не заботится о такой скуке. У нас есть Собственность, которой нет дела до игроков. Но объект Player знает всю эту информацию. Он ведет учет того, чем владеет каждый игрок, и может легко получить доступ к нужным данным.

Итак, если бы это был я, я бы создал метод Player.performMove (Die d).Имеет легкий доступ к счетам. Это также обеспечивает наименьшую связь между классами.

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

5
ответ дан 4 December 2019 в 15:12
поделиться

Я согласен, вариант №1 кажется лучше.

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

// in main class
user.landOn(space);
if (space.containsProperties()) doSomething(); // Option #1 for some user-interaction code

// in User.java
public void landOn(Space s) {
    // do some checks
    s.land(this);
    if (s.containsProperties()) {...} // Option #2
    // something else?
}

// in GetMoneySpace.java
@Override
public void land(User u) {
    u.awardCash(200);
    // Option #3 - no properties so nothing here
}

Это гораздо больше ООП (и, на мой взгляд, лучше), чем что-то вроде

if (space.isCashAwardSpace()) {
    user.awardCash(space.getAward());
}
if (user.something()) doSomething(); // Some user-interaction code
5
ответ дан 4 December 2019 в 15:12
поделиться

Использовать первый дизайн. У вас будет класс Property и подкласс специальных свойств, переопределив поведение по умолчанию.

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

Примеры классов:

  • Свойство
    • имя
    • цена
    • baseRent
    • houseCount
    • hotelCount
    • ипотека
    • getCurrentRent ()
  • RailRoad расширяет свойство
  • Утилита расширяет свойство
  • Board
    • свойства
  • Пользователь
    • токен
    • playerName
    • currentProperty
    • ownProperties
    • buyProperty ()
    • payRentOnProperty ()
    • mortgageProperty ()
    • move ()
1
ответ дан 4 December 2019 в 15:12
поделиться

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

Что касается взаимодействия, то, как правило, плохие новости для дизайна, когда у вас есть « класс бога », который выполняет всю работу и просто запрашивает информацию у других классов. Есть много способов попасть в эту ловушку; один из способов определить, имеете ли вы дело с божественным классом, - это найти имя класса, включая Manager или System .Таким образом, вероятно, не лучшая идея иметь своего рода «игровой менеджер», который запрашивает данные у всех других объектов, вносит все изменения и все отслеживает. По возможности устраните их.

Бог-классы нарушают концепцию инкапсуляции , которая подразумевает нечто большее, чем сокрытие данных (хотя это определенно большая часть этого). Хорошая инкапсуляция означает, что связанные методы и данные являются частью единого объекта. Например, свойство не должно запрашивать своего владельца, поэтому поле, содержащее ссылку на Player , может нарушать инкапсуляцию. Некоторые из этих нарушений инкапсуляции вообще не очевидны, и их трудно обнаружить. При проектировании объекта постарайтесь определить наименьший объем информации об объекте, который необходимо передать внешним объектам. Отрежьте все ненужное.

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

  • Space класс, содержащий базовые данные и методы, общие для все клетки (например, их положение на доске, занято или нет и т. д.).
  • Подклассы перемещаются от наиболее распространенных ( Свойство и Утилита ) к наиболее уникальным ( Go , Jail , FreeParking и т. Д., Вероятно, одиночные) с полями и методами, связанными с каждым из них.
  • Класс Player , содержащий информацию об игроке.
  • GameState класс, связанный с состоянием игры; чья очередь, сколько домов осталось в банке и так далее.

Удачи вам в игре и продолжении учебы.

Естественно, Google - ваш друг, но вот несколько примеров, которые я бы порекомендовал прочитать:

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

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

1
ответ дан 4 December 2019 в 15:12
поделиться

Я бы выбрал ваш первый подход. Он инкапсулирует поведение там, где это необходимо. Итак, у вас были бы подклассы Space для Utilities, Properties, GotoJail, FreeParking - в основном всех различных категорий пространств. Что группирует категорию, так это обычное поведение.

Ваши пространства свойств могут сами иметь объект группы в качестве члена, например чтобы сгруппировать все темно-синие свойства вместе.

Что касается взаимодействия с пользователем, вы передаете экземпляр Board (или, лучше, GameController) каждому пространству, чтобы он знал, частью какой игры он является, и мог влиять на игру. Затем пространство может вызывать определенные действия на доске, такие как перемещение фишки, задание вопроса пользователю и т. Д. Главное, что существует разделение - взаимодействие с пользователем не происходит внутри каждого пространства, но пространству разрешено попросите, чтобы произошло какое-то взаимодействие или чтобы кусок переместился. Ваш GameController должен фактически выполнять взаимодействие или перемещать элементы и т. Д. Такое разделение упрощает тестирование, а также предоставляет альтернативные реализации по мере необходимости (например, разные правила игры в разных редакциях / странах?)

1
ответ дан 4 December 2019 в 15:12
поделиться

Вариант 2 не имеет особого смысла, или, по крайней мере, он не так понятен мне, как вариант 1. В варианте 1 вам не нужно обрабатывать взаимодействие с пользователем внутри вашего космического объекта. Вы можете иметь в своем основном классе или отдельном классе отдельный класс, предназначенный для обработки взаимодействия с пользователем:

public void move(Player p, int spaces){
    Space landingSpace = board.getLandingSpace(p,spaces);
    landingSpace.land(p); //apply your logic here
}

Как вы можете видеть, класс Space отвечает за проверку Player p, который собирается приземлиться на это пространство. Он применяет любую пользовательскую логику, проверяет, достаточно ли у него денег, является ли это чем-то, чем владеет игрок, и т.д. Каждый подкласс Космос будет иметь свой собственный набор правил, как вы описали в варианте 1.

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

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