2013-09-01 2 views
1

В настоящее время я работаю над дизайном Java-игры, и я столкнулся с проблемой с круговой зависимостью между классами. Вот (упрощенный) пример моей текущей задачи:Как удалить круговую зависимость в пошаговой игре?

class Game 
class Player 
class Ability 

Игры имеют Игроки, которые в свою очередь имеют способности (например, заклинание или атака). Способность имеет метод, как:

public void perform(Player source, Game game); 

Вопрос заключается в том, что способность требует знаний игры (и игрок/объект игры) для того, чтобы выполнять свои действия. Есть ли способы решить это?


Обновление: Я ценю ответы. Теперь я вижу, что способности не должны принадлежать Игрокам. У меня возникли проблемы с выяснением того, как связать Игроков и Способностей. Например, возьмите игру, такую ​​как Pokemon, где у каждого существа есть способности, которые он может использовать. Или возьмите коллекционную карточную игру, где каждая карта может иметь способности, которые влияют на любую часть игры. Должен быть какой-то способ определить, какие игроки (или любой объект, способный использовать способ) могут использовать какие способности, даже если способности не принадлежат непосредственно Игрокам.

ответ

4

Почему круговые зависимости классов внутри одного и того же пакета (при условии, что они находятся в одном и том же pacakge) проблема? ИМО, когда я думаю о круговых зависимостях, я склонен думать на уровне пакета, а не на уровне класса. Круговые зависимости пакетов более проблематичны, потому что это затрудняет реорганизацию кода. Классы в том же пакете, вероятно, будут связаны, и некоторая жесткая связь когда-то неизбежна.

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

+0

Согласитесь с этими соображениями. – Woot4Moo

3

Ваш класс умения не обязательно должен знать, что это в игре. Вам нужен класс Engine или Environment, который представляет правила и составляет игру. Это позволит вам бросить готовых игроков в бесконечное количество игровых движков. Например, вы можете иметь LowGravityEngine и QuantumEngine. Эти двигатели позволят улучшить дизайн с точки зрения отделения вашей модели (игрока) от контроллера (Engine или Game).

Если вы не хотите, чтобы двигатели реорганизовали вашу Игру, чтобы взять объекты Игрока, а не способность играть. Это не имеет смысла. Например, в Монополии кусок собаки не знает, как купить недвижимость.

0

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

Например, в ваших Player полях:

private Game parent; 

Тогда, скажем, в вашем Player конструктору:

public Player(Game parent) { 
    this.parent = parent; 
} 

И, конечно же, общественный способ, такой как:

public final Game getParent() { 
    return parent; 
} 

Тогда вы можете позвонить в perform с помощью только Player экземпляр в качестве аргумента и запросить поля экземпляра Game в теле метода.

В случае, если ваши классы Game предоставляют только статические данные (например, «правила»), вы также можете передать Class в качестве аргумента вместо экземпляра Game.

Однако это одно решение из бесконечного числа.

Решение Woot4Moo имеет для меня прекрасный смысл.

0

Если perform функции Ability нужны знания о Player, вы фактически используя strategy design pattern, так как вы можете выбрать любого из ряда способностей на основе параметров, которые вы массу функции perform (эти параметры бытия, в данном случае, Player и Game).

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

Смежные вопросы