あなたの手の唯一の性質は、それが他の1つを打ち負かしているということです。
次に、ハンドフォームごとに1つの具象型を使用しているときにコードを繰り返さないようにする必要があるため、パラメーター化する必要があります。許可できる自由のレベルに応じて、これは保護されたメンバーと同じくらい簡単にすることができます。
abstract class Hand {
protected $beats;
final public function beats(Hand $opponent) {
return $opponent instanceof $this->beats;
}
}
class Rock extends Hand {
protected beats = 'Scissors';
}
class Paper extends Hand {
protected beats = 'Rock';
}
class Scissors extends Hand {
protected beats = 'Paper';
}
これは、非常に単純な形式の標準的なテンプレートメソッドパターンだと思います。
これを、実際のコードのクレジットを取得する必要があるルシタニア人の回答と比較してください。少し並べ替えたところです。しかし、ほんの少しです。
さらに、はるかに優れた関数とパラメーターの命名のために、@Leighにクレジットを与える必要があります。これにより、コメントの必要性が減るはずです。
Lusistanianが提案する2番目の選択肢は、戦略パターンで表すことができます。また、やや簡単です。
class EvaluateHands
{
private $rules;
public function __construct(array $rules)
{
$this->rules = $rules;
}
public function compareHands(Hand $hand1, Hand $hand2)
{
return $this->rules[get_class($hand1)] === get_class($hand2) ? $hand1 : $hand2;
}
}
new EvaluateHands(
array(
'Rock' => 'Scissors',
'Paper' => 'Rock',
'Scissor' => 'Paper'
)
);
2つのハンドの比較はEvaluateHands
、(ゲームのルールが変更された場合でも)構成可能なタイプに完全にカプセル化されていますが、ハンドは同じままです。
abstract class Hand {}
class Rock extends Hand {}
class Paper extends Hand {}
class Scissors extends Hand {}
このコードのクレジットは、gordon(Lusistanianの隣)に送られます。