Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Introduction To Value Objects

turanct
November 13, 2015

Introduction To Value Objects

turanct

November 13, 2015
Tweet

More Decks by turanct

Other Decks in Programming

Transcript

  1. 5 m > 499 cm ? 5 > 499 ?

    5 m > 4.99 m ?
  2. 5 m - 499 cm = ? 5 - 499

    = ? 5 m - 4.99 m = ?
  3. Recap • Encapsulate data that belongs together • Make invalid

    state impossible to represent • Values are immutable
  4. final class Length { private $amount; private $unit; public function

    __construct($amount, Unit $unit) { $this->amount = ( float) $amount; $this->unit = $unit; } }
  5. final class Length { // … public function __construct($amount, Unit

    $unit) { $this->assertZeroOrMore($amount); $this->amount = ( float) $amount; $this->unit = $unit; } private function assertZeroOrMore($amount) { if ($amount < 0) { throw new LengthShouldBeZeroOrMore (); } } }
  6. final class Unit { private $unit; public function __construct($unit) {

    $this->assertKnownUnit($unit); $this->unit = ( string) $unit; } public function assertKnownUnit($unit) { if (!in_array((string) $unit, static::KNOWN_UNITS)) { throw new UnknownUnit($unit); } } }
  7. final class Length { // … public function isSameUnit(Length $otherLength)

    { return $this->unit->equals($otherLength->unit); } }
  8. final class Unit { // … public function equals(Unit $otherUnit)

    { return $this->unit == $otherUnit->unit; } }
  9. final class Length { // … private function assertSameUnit( Length

    $otherLength) { if (!$this->isSameUnit($otherLength)) { throw new CanNotCompareDifferentUnits (); } } public function greaterThan(Length $otherLength) { $this->assertSameUnit($otherLength); return $this->amount > $otherLength->amount; } }
  10. final class Length { // … public function add(Length $otherLength)

    { $this->assertSameUnit($otherLength); return new static ( $this->amount + $otherLength->amount, $this->unit ); } }
  11. final class Length { // … public function __toString() {

    return $this->amount . ' ' . $this->unit->__toString(); } }
  12. final class Length { // … public static function fromString($string)

    { if (!preg_match('/^(\d+(?:[.,]?\d+?)?)\s(\w*)$/ ', $foo, $matches)) { throw new InvalidStringRepresentation( ); } return new static ( $matches[1], $matches[2] ); } }
  13. class StackTest extends PHPUnit_Framework_TestCase { function it_adds_two_lengths_of_the_same_unit() { $length1 =

    new Length(10, new Unit('m')); $length2 = new Length(5, new Unit('m')); $expected = new Length(15, new Unit('m')); $this->assertEquals( $expected, $length1->add($length2) ); } }
  14. class StackTest extends PHPUnit_Framework_TestCase { // … /** * @expectedException

    CanNotCompareDifferentUnits */ function it_throws_when_adding_lengths_of_different_unit() { $length1 = new Length(10, new Unit('m')); $length2 = new Length(5, new Unit('cm')); $length1->add($length2); } // etcetera }
  15. other examples • money • telephone number • bank account

    • gender • temperature • DateTime? • interval • ...