12

私が次の構造を持っているとしましょう:

abstract class Hand {}

class Rock extends Hand {}
class Paper extends Hand {}
class Scissors extends Hand {}

Hand::compareHands(Hand $hand1, Hand $hand2)目標は、ジャンケンで勝った手を返す関数 (またはメソッド) を作成することです。

これは s の束で非常に簡単ifですが、要点は、手続き型コードではなくポリモーフィズムに依存する、より堅牢な構造を持つことです。

PSこれは、誰かが求めている場合、実際の製品コードで行われます。これは、ある種の課題や宿題ではありません。(実際にはじゃんけんではありませんが、要点はわかります)。

4

3 に答える 3

12

あなたの手の唯一の性質は、それが他の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の隣)に送られます。

于 2012-10-04T11:50:29.960 に答える
5

これはどう?

class Scissors extends Hand implements Beats<Paper> {}

Beats<> は、署名が次のような汎用インターフェイスです。

interface Beats<Hand> {}
于 2012-10-03T21:31:08.520 に答える
3

PHPチャットから

OOP スタイル

<?php
interface Hand {
    function beats(Hand $hand);
}

class Rock implements Hand {
    public function beats(Hand $hand) {
        return $hand instanceof Scissors;
    }
}
class Paper implements Hand {
    public function beats(Hand $hand) {
        return $hand instanceof Rock;
    }
}

class Scissors implements Hand {
    public function beats(Hand $hand) {
        return $hand instanceof Paper;
    }
}

シンプルな機能

<?php
const PAPER = 1;
const ROCK = 2;
const SCISSORS = 3;

function whichHandWon($hand1, $hand2) {
    $winners = [PAPER => ROCK, ROCK => SCISSORS, SCISSORS => PAPER];
    return intval($winners[$hand1] !== $hand2) + 1;
}
于 2012-10-03T21:32:32.387 に答える