카드에 두 가지 중요한 기능 세트가있는 카드 게임을 모델링하려고합니다.
첫 번째는 효과입니다. 카드를 플레이 할 때 발생하는 게임 상태의 변경 사항입니다. 효과의 인터페이스는 다음과 같습니다.
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);
그리고 "play"대신 "activate"라고 부르는 것을 제외 Ability
하고 Effect
는 정확히 같은 서명을 가지고 있다는 것을 알고 있습니다.
서명이 동일한 여러 개의 인터페이스를 갖는 것은 좋지 않습니까? 간단히 하나만 사용해야하고 동일한 인터페이스의 두 세트가 있어야합니까? 따라서 :
Set<Effect> effects;
Set<Effect> abilities;
그렇다면, 더 많은 기능이 출시됨에 따라 동일하지 않은 경우, 특히 분기가 다른 경우 (즉, 둘 중 하나만 얻는 것과는 반대로 다른 쪽에서는하지 말아야 할 것을 얻는 경우) 리팩토링 단계를 진행해야합니다. 다른 하나는 완전한 하위 집합입니다)? 특히 무언가를 변경하자마자 그것들을 결합하는 것이 지속될 수 없다고 우려하고 있습니다.
작은 글씨 :
나는이 질문이 게임 개발에 의해 생긴다는 것을 알고 있지만, 게임이 아닌 개발에서 쉽게 발생할 수있는 일종의 문제라고 생각한다. 하나 이상의 비즈니스 영향으로 수행 한 모든 프로젝트 ... 또한 사용 된 스 니펫은 Java 스 니펫이지만, 이는 여러 객체 지향 언어에도 쉽게 적용될 수 있습니다.