バックグラウンド
私が取り組んでいる実際の問題は次のとおりです。カードゲームMagic:The Gatheringでカードを表現する方法が必要です。ゲーム内のほとんどのカードは見た目が普通のカードですが、一部は2つの部分に分かれており、それぞれに名前が付いています。これらの2部構成のカードの各半分は、カード自体として扱われます。そのため、明確にするためにCard
、通常のカード、または2部構成のカードの半分(つまり、名前が1つだけのカード)を参照するためにのみ使用します。
したがって、基本タイプのCardがあります。これらのオブジェクトの目的は、実際には単にカードのプロパティを保持することです。彼らは本当に自分で何もしません。
interface Card {
String name();
String text();
// etc
}
には2つのサブクラスがありCard
、私はこれを呼び出していますPartialCard
(2部構成のカードの半分)とWholeCard
(通常のカード)。 PartialCard
には2つの追加メソッドがあります:PartialCard otherPart()
とboolean isFirstPart()
。
代表者
私がデッキを持っている場合、それはWholeCard
sではなくCard
sで構成されている必要Card
があり、a はである可能性がありPartialCard
、それは意味がありません。そのため、「物理カード」を表すオブジェクト、つまり1つWholeCard
または2つPartialCard
のsを表すことができるオブジェクトが必要です。私は暫定的にこのタイプを呼んでいるRepresentative
、とCard
方法を持っているでしょうgetRepresentative()
。Aは、Representative
カード(複数可)にほとんど直接的な情報を提供するだろう、それはそれ/それらへの唯一のポイントだろう、を表します。今、私の素晴らしい/クレイジー/愚かなアイデア(あなたが決める)は、WholeCardがとの両方 Card
を継承するということですRepresentative
。結局のところ、彼らは自分自身を表すカードです!WholeCardsはgetRepresentative
として実装できますreturn this;
。
に関してはPartialCards
、それらは自分自身を表しRepresentative
てはいませんが、a Card
ではなく、2つPartialCard
のにアクセスするためのメソッドを提供する外部を持っています。
このタイプの階層は理にかなっていると思いますが、複雑です。Card
sを「概念的なカード」と考え、Representative
sを「物理的なカード」と考えると、ほとんどのカードは両方です。物理的なカードには実際には概念的なカードが含まれており、それらは同じものではないと主張することができると思いますが、私はそれらが同じだと主張します。
型キャストの必要性
のでPartialCard
、SとWholeCards
ともにCard
、S、及びそれらを分離するためには良い理由は、通常はありません、私は通常、ちょうどと仕事ができると思いますCollection<Card>
。そのPartialCard
ため、追加のメソッドにアクセスするためにs をキャストする必要がある場合があります。今は、明示的なキャストが本当に好きではないので、ここで説明するシステムを使用しています。そしてのようにCard
、それらが表す実際のにアクセスするにはRepresentative
、WholeCard
またはのいずれかにキャストする必要があります。Composite
Card
要約のために:
- ベースタイプ
Representative
- ベースタイプ
Card
- タイプ
WholeCard extends Card, Representative
(アクセスは不要、それ自体を表す) - タイプ
PartialCard extends Card
(他の部分へのアクセスを許可) - タイプ
Composite extends Representative
(両方の部分にアクセスできます)
これは非常識ですか?実際にはかなり理にかなっていると思うが、正直なところわからない。