Próbuję modelować grę karcianą, w której karty mają dwa ważne zestawy funkcji:
Pierwszy to efekt. Są to zmiany stanu gry, które mają miejsce podczas gry w kartę. Interfejs efektu jest następujący:
boolean isPlayable(Player p, GameState gs);
void play(Player p, GameState gs);
Możesz uznać kartę za możliwą do zagrania tylko wtedy, gdy jesteś w stanie pokryć jej koszt, a wszystkie jej efekty można zagrać. Tak jak:
// 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;
}
Jak dotąd, całkiem proste.
Innym zestawem funkcji na karcie są zdolności. Te umiejętności to zmiany stanu gry, które możesz aktywować do woli. Kiedy wymyśliłem interfejs dla nich, zdałem sobie sprawę, że potrzebowali metody określania, czy można je aktywować, czy nie, oraz metody implementacji aktywacji. W końcu jest
boolean isActivatable(Player p, GameState gs);
void activate(Player p, GameState gs);
I zdaję sobie sprawę, że z wyjątkiem nazywania go „aktywuj” zamiast „graj” Ability
i Effect
mam dokładnie taki sam podpis.
Czy źle jest mieć wiele interfejsów z identycznym podpisem? Czy powinienem po prostu użyć jednego i mieć dwa zestawy tego samego interfejsu? Tak więc:
Set<Effect> effects;
Set<Effect> abilities;
Jeśli tak, to jakie kroki refaktoryzacyjne powinienem podjąć, jeśli stają się one nieidentyczne (w miarę uwalniania większej liczby funkcji), szczególnie jeśli są rozbieżne (tj. Oboje zyskują coś, czego nie powinni inni, a nie tylko jedną zdobywają a drugi jest kompletnym podzbiorem)? Szczególnie martwię się, że ich połączenie nie będzie zrównoważone, gdy tylko coś się zmieni.
Drobnym drukiem:
Zdaję sobie sprawę, że to pytanie powstaje podczas tworzenia gier, ale wydaje mi się, że jest to rodzaj problemu, który równie łatwo może wkraść się w programowanie inne niż gry, szczególnie przy próbie dostosowania modeli biznesowych wielu klientów w jednej aplikacji, jak to się dzieje w przypadku prawie każdy projekt, który kiedykolwiek zrealizowałem z więcej niż jednym wpływem biznesowym ... Ponadto, fragmenty są fragmentami Java, ale równie dobrze można je zastosować do wielu języków obiektowych.