-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
reusable value-objects w/ better type safety #182
Comments
Hello, |
@sebastianstucke87 Because you didn't find any article about traits, here us one that could help to understand more features about traits. |
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). 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('[email protected]'),
new Email('[email protected]'),
); 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('[email protected]'),
new Email('[email protected]'),
)); 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 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.).
The text was updated successfully, but these errors were encountered: