Я пытаюсь смоделировать карточную игру, в которой у карт есть два важных набора функций:
Первый эффект. Это изменения состояния игры, которые происходят при игре на карте. Интерфейс для эффекта выглядит следующим образом:
boolean isPlayable(Player p, GameState gs);
void play(Player p, GameState gs);
И вы можете считать карту пригодной для игры, если и только если вы можете удовлетворить ее стоимость, и все ее эффекты являются играбельными. Вот так:
// in Card class
boolean isPlayable(Player p, GameState gs) {
if(p.resource < this.cost) return false;
for(Effect e : this.effects) {
if(!e.isPlayable(p,gs)) return false;
}
return true;
}
Ладно, пока все довольно просто.
Другой набор функций на карте - это способности. Эти способности - это изменения состояния игры, которые вы можете активировать по своему желанию. Когда я придумал интерфейс для них, я понял, что им нужен метод для определения, можно ли их активировать или нет, и метод для реализации активации. Это в конечном итоге
boolean isActivatable(Player p, GameState gs);
void activate(Player p, GameState gs);
И я понимаю, что за исключением того, что он называется «активировать», а не «играть», Ability
и Effect
иметь точно такую же подпись.
Плохо ли иметь несколько интерфейсов с одинаковой подписью? Должен ли я просто использовать один и иметь два набора одного и того же интерфейса? Как так:
Set<Effect> effects;
Set<Effect> abilities;
Если да, то какие шаги по рефакторингу я должен предпринять в будущем, если они станут неидентичными (по мере того, как будет выпущено больше функций), особенно если они расходятся (т. Е. Они оба приобретают то, чего не должен другой, в отличие от одного выигрыша) а другой является полным подмножеством)? Я особенно обеспокоен тем, что объединение их будет неустойчивым, как только что-то изменится.
Мелкий шрифт:
Я признаю, что этот вопрос порожден разработкой игр, но я чувствую, что это та проблема, которая может так же легко всплыть в неигровой разработке, особенно при попытке разместить бизнес-модели нескольких клиентов в одном приложении, как это происходит почти с каждый проект, который я когда-либо делал, имел более чем одно влияние на бизнес ... Кроме того, используемые фрагменты - это фрагменты Java, но это также легко можно применить ко множеству объектно-ориентированных языков.