/ Gists / Value object - Cards example
On gists

Value object - Cards example

PHP PHP Patterns

usage.php Raw #

<?php

// c
$pickedCard = new Card(new CardSuit(CardSuit::SPADES), new CardRank(CardRank::ACE));

// d
$aceSpade = new Card(CardSuit::spades(), CardRank::ace());
$twoSpade = new Card(CardSuit::spades(), CardRank::two());
if ($aceSpace->isGreaterThan($twoSpade)) {
    // do something when greater, such as sum the weight to count points
}

Card.php Raw #

<?php

namespace App\Domain;

class Card
{
    public CardSuit $suit;
    public CardRank $rank;

    public function __construct(CardSuit $suit, CardRank $rank)
    {
        $this->suit = $suit;
        $this->rank = $rank;
    }

    public function suit(): CardSuit
    {
        return $this->suit;
    }

    public function rank(): CardRank
    {
        return $this->rank;
    }
}

CardRank.php Raw #

<?php

namespace App\Domain;

class CardRank
{
    public const ACE = 'A';
    public const KING = 'K';
    public const QUEEN = 'Q';
    public const JACK = 'J';
    public const TEN = 'X';
    public const NINE = '9';
    public const EIGHT = '8';
    public const SEVEN = '7';
    public const SIX = '6';
    public const FIVE = '5';
    public const FOUR = '4';
    public const THREE = '3';
    public const TWO = '2';

    public const RANKS = [
        self::ACE,
        self::KING,
        self::QUEEN,
        self::JACK,
        self::TEN,
        self::NINE,
        self::EIGHT,
        self::SEVEN,
        self::SIX,
        self::FIVE,
        self::FOUR,
        self::THREE,
        self::TWO
    ];

    public const WEIGHTS = [
        self::ACE => 20,
        self::KING => 13,
        self::QUEEN => 12,
        self::JACK => 11,
        self::TEN => 10,
        self::NINE => 9,
        self::EIGHT => 8,
        self::SEVEN => 7,
        self::SIX => 6,
        self::FIVE => 5,
        self::FOUR => 4,
        self::THREE => 3,
        self::TWO => 2
    ];

    private string $value;

    public function __construct(string $value)
    {
        if (!in_array($value, self::RANKS)) {
            throw new \InvalidArgumentException("`$value` is not a valid card rank.");
        }

        $this->value = $value;
    }

    public function __toString()
    {
        return $this->value;
    }

    public function value(): string
    {
        return $this->value;
    }

    public function weight(): int
    {
        return self::WEIGHTS[$this->value];
    }

    public function isGreaterThan(CardRank $cardRank): bool
    {
        return $this->weight() > $cardRank->weight();
    }

    // Some helper static functions can be created to be more readable

    public static function two(): CardRank
    {
        return new self(self::TWO);
    }

    public static function ace(): CardRank
    {
        return new self(self::ACE);
    }
}

CardSuit.php Raw #

<?php

namespace App\Domain;

class CardSuit
{
    public const HEARTS = 'H';
    public const DIAMONDS = 'D';
    public const CLUBS = 'C';
    public const SPADES = 'S';

    public const SUITS = [
        self::HEARTS,
        self::DIAMONDS,
        self::CLUBS,
        self::SPADES,
    ];

    private string $value;

    public function __construct(string $value)
    {
        if (!in_array($value, self::SUITS)) {
            throw new \InvalidArgumentException("`$value` is not a valid card suit.");
        }

        $this->value = $value;
    }

    public function __toString()
    {
        return $this->value;
    }

    public function value(): string
    {
        return $this->value;
    }

    // Some helper static functions can be created to be more readable

    public static function spades(): CardSuit
    {
        return new self(self::SPADES);
    }
}