Kuba Werłos
Wiele osób wierzy, że stosuje DDD,
ponieważ jeden z katalogów nazwali „Domain”.
Jeśli używamy powszechnie znanego konceptu,
to przestrzegajmy jego zasad.
<?php
final class Person
{
public float $height;
public float $weight;
}
int $dayOfMonth | 42 | |
float $distance | -1.5 | |
string $forename | X Æ A-12 |
$ php -a
Interactive shell
php > var_export(0.1 + 0.2 === 0.3);
bool(false)
$ php -a
Interactive shell
php > var_dump(0.1 + 0.2);
float(0.30000000000000004)
Value Object to jeden z najważniejszych
elementów Domain-Driven Design.
Value Object może być używany
bez korzystania z Domain-Driven Design.
<?php
$point = new Point();
// invalid state
$point->x = 2;
$point->y = 3;
<?php
$point = new Point(2, 3);
<?php
final class DateRange
{
public function __construct(
public string $uuid,
public DateTimeInterface $from,
public DateTimeInterface $to,
) {}
}
<?php
final class DateRange
{
public function __construct(
public DateTimeInterface $from,
public DateTimeInterface $to,
) {}
}
<?php
$name1 = new Name('Alex');
$name2 = new Name('Alex');
assert($name1 === $name2); // false
<?php
$name1 = new Name('Alex');
$name2 = new Name('Alex');
assert($name1 == $name2); // true
assert($name1->equals($name2)); // true
<?php
$point = new Point(2, 3);
$point->setX(4);
echo $point->toString();
// (x: 4, y: 3)
<?php
$point = new Point(2, 3);
$new = $point->setX(4);
echo $point->toString();
// (x: 2, y: 3)
echo $new->toString();
// (x: 4, y: 3)
<?php
$point = new Point(2, 3);
$point->__construct(7, 8);
<?php
readonly class Point
{
public function __construct(
public int $x,
public int $y,
) {}
}
<?php
class Point
{
public static function create(int $x, int $y)
{
return new self($x, $y);
}
private function __construct(
public int $x,
public int $y,
) {}
}
<?php
$dateRange = new DateRange(
new DateTime('today'),
new DateTime('yesterday'),
);
// Exception: start cannot be after end
<?php
$dateRange = new DateRange($d1, $d2);
echo $dateRange->isShorterThanWeek();
// true / false
<?php
#[Embeddable]
class Address
{
#[Column(type: 'string')]
private string $street;
#[Column(type: 'string')]
private string $city;
#[Column(type: 'string')]
private string $country;
}
<?php
#[Entity]
class User
{
#[ORM\Id]
#[ORM\Column(type: 'uuid', unique: true)]
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
#[ORM\CustomIdGenerator(class: UuidGenerator::class)]
private UuidInterface $id;
#[Embedded(class: Address::class)]
public Address $address;
}
<?php
$user = $repository->findOneBy(['address.country' => 'PL']);
$user->address = new Address(
'Podwale 37/38',
'Wrocław',
'PL',
);