배경
다음은 실제 작업중인 문제입니다. 카드 게임 Magic : The Gathering 에서 카드를 표현하는 방법을 원합니다 . 게임에서 대부분의 카드는 일반적인 모양의 카드이지만 일부는 각각 고유 한 이름을 가진 두 부분으로 나뉩니다. 이 두 부분으로 된 카드의 각 절반은 카드 자체로 취급됩니다. 명확성을 위해, 나는 Card
단지 일반 카드이거나 두 부분으로 된 카드의 절반 (즉, 이름이 하나만있는)을 나타내는 데에만 사용 합니다.
기본 유형 인 카드가 있습니다. 이러한 객체의 목적은 실제로 카드의 속성을 유지하는 것입니다. 그들은 실제로 스스로 아무것도하지 않습니다.
interface Card {
String name();
String text();
// etc
}
의 두 개의 서브 클래스가 있는데 Card
, PartialCard
(2 파트 카드의 절반)과 WholeCard
(일반 카드) 라고 부릅니다 . PartialCard
두 가지 추가 방법이 있습니다 : PartialCard otherPart()
및 boolean isFirstPart()
.
대표자
나는 갑판이있는 경우,이를 구성해야 WholeCard
하지, S Card
, A는 같은이야 Card
될 수있다 PartialCard
, 그것은 의미가 없다. 그래서 저는 "물리적 카드"를 나타내는 객체, 즉 하나 WholeCard
또는 두 개의 객체를 원합니다 PartialCard
. 나는이 타입을 잠정적으로 호출 Representative
하고 Card
있으며 메소드를 가질 것이다 getRepresentative()
. A Representative
는 자신이 나타내는 카드에 대한 직접적인 정보를 거의 제공하지 않으며 카드 만 가리 킵니다. 이제, 나의 화려한 / 미친 / 바보 같은 아이디어는 (당신이 결정)에서 해당 WholeCard 상속입니다 모두 Card
와 Representative
. 결국, 그들은 자신을 나타내는 카드입니다! WholeCards는로 구현할 수 getRepresentative
있습니다 return this;
.
에 관해서는 PartialCards
, 그들은 자신을 대표하지 않지만, 외부 Representative
가 아닌 Card
두 가지에 액세스하는 방법을 제공합니다 PartialCard
.
이 유형 계층 구조는 의미가 있다고 생각하지만 복잡합니다. 우리가 Card
"개념적 카드"로 생각 Representative
하고 "물리적 카드 "로 생각한다면 , 대부분의 카드는 둘 다입니다! 실제 카드에는 실제로 개념적인 카드가 포함되어 있으며 그것들이 같은 것은 아니라고 주장 할 수 있다고 생각합니다.
타입 캐스팅의 필요성
때문에 PartialCard
S 그리고 WholeCards
모두 Card
들, 그리고 그들을 분리하는 것이 더 좋은 이유가, 나는 일반적으로 단지와 함께 일하게 될 것입니다 Collection<Card>
. 그래서 때로는 PartialCard
추가 방법에 액세스하기 위해을 캐스팅해야 합니다. 지금 은 명시 적 캐스트를 좋아하지 않기 때문에 여기에 설명 된 시스템을 사용 하고 있습니다 . 그리고 같은 Card
, Representative
중 하나에 캐스트 할 필요 WholeCard
또는 Composite
실제 액세스하기 위해, Card
그들이 대표들.
요약하면 다음과 같습니다.
- 기본 유형
Representative
- 기본 유형
Card
- 유형
WholeCard extends Card, Representative
(액세스가 필요하지 않으며 자체를 나타냄) - 유형
PartialCard extends Card
(다른 부분에 대한 액세스 권한 부여) - 유형
Composite extends Representative
(두 부분 모두에 접근 가능)
이건 미쳤어? 나는 그것이 실제로 의미가 있다고 생각하지만 솔직히 확실하지 않습니다.