La única característica de su mano es que está superando a uno solo.
Luego no desea repetir el código mientras tiene un tipo de concreto por forma de mano, por lo que debe parametrizar. Dependiendo del nivel de libertad puede permitir, esto puede ser tan simple como un miembro protegido:
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';
}
Creo que este es el plantilla de patrón estándar método aquí, en una forma muy simple.
Compara esto con Lusitanian's answer que debería obtener los créditos para el código real, simplemente lo he reordenado un poco. Pero solo muy poco.
Además, tengo que dar créditos a @Leigh for the far better function and parameter naming. Esto debería reducir la necesidad de comentarios.
La segunda alternativa que sugiere Lusistanian se puede representar con el patrón de estrategia . Es también un poco hacia adelante recta:
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'
)
);
La comparación entre dos manos ha sido totalmente encapsulado en el tipo EvaluateHands
que es aún configurable (si las reglas del juego cambian), mientras que las manos se mantienen igual:
abstract class Hand {}
class Rock extends Hand {}
class Paper extends Hand {}
class Scissors extends Hand {}
Créditos para este código vaya a gordon (al lado de Lusistanian).
Las instancias de 'Hand' no se comparan entre sí. Es por eso que tenemos 'Cerebros'. –
@tereko: Interesante, ¿tiene una solución que involucre 'Cerebro'? –