Open sebastianstucke87 opened 3 years ago
Hello, You can achieve the same result with inheritance. Can you explain why you prefer to use traits ? Thanks
@sebastianstucke87 Because you didn't find any article about traits, here us one that could help to understand more features about traits. Overriding & Extending a PHP Trait Method | Andy Carter https://andy-carter.com/blog/overriding-extending-a-php-trait-method
Using traits in Value Objects is an indicator that you are using Value Objects incorrectly. A Value Object is a Minimum Viable Universal Unit, not a Unique Unit. It is not good to create a unique Value Object for each variable (DRY). An exception can be Value Objects for identifiers for which the uniqueness of the type is important, and the code is almost always identical.
final class Email
{
private string $email;
public function __construct(string $email)
{
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new \InvalidArgumentException(/* ... */);
}
$this->email = $email;
}
public function getEmail(): string
{
return $this->email;
}
public function __toString(): string
{
return $this->email;
}
}
final class User
{
public function updateEmail(Email $work, Email $personal): void
{
/* ... */
}
}
$user->updateEmail(
new Email('ohn_doe@acme.com'),
new Email('jonny1337@aolmail.com'),
);
For more control over the data structure, you can use the Value Object to describe a group of object properties.
final class UserContactData
{
private Email $work;
private Email $personal;
public function __construct(Email $work, Email $personal)
{
$this->work = $work;
$this->personal = $personal;
}
public function getWorkEmail(): Email
{
return $this->work;
}
public function getPersonalEmail(): Email
{
return $this->personal;
}
}
final class User
{
private UserContactData $contact_data;
public function changeContactData(UserContactData $contact_data): void
{
$this->contact_data = $contact_data
}
}
$user->changeContactData(new UserContactData(
new Email('ohn_doe@acme.com'),
new Email('jonny1337@aolmail.com'),
));
If you are using the Doctrine, then you can describe it through Embeddables.
The topic of traits has already been raised in another issue #130. So far, there are no adequate examples of using traits. I would also like to see a good example of using traits here.
I didn't really understand the point of traits until recently and now I can't live without them. And since I didn't find anything about traits on here, I wanted to share my findings. Is this something you are interested in?
In this first example, the two arguments
workEmail
andpersonalEmail
are switched. But according to the signature ofupdateEmail
, everything is in order since both arguments are of type string:Here we created the value-object
EmailTrait
to wrap any email-value. But instead of a class, the value-object is a trait. We re-use the trait inWorkEmail
andPersonalEmail
. Both have the same behavior asEmailTrait
but have their own typeWorkEmail
andPersonalEmail
respectively.Now in this second example, the signature of
updateEmail
is absolutely clear about its argument types and can't be misused:This is especially helpful, when there are a lot of primitive values that behave essentially the same, but represent different things in the domain (IDs, postal addresses, event-objects etc.).