-
Notifications
You must be signed in to change notification settings - Fork 5
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
Value types/value objects - use clearly defined types for anything that would otherwise be a scalar or composition of scalars #3
base: feature/oop-login-logout
Are you sure you want to change the base?
Conversation
For these value objects instead creating of own method |
@themark147 good question: I prefer to use Here's an example of code that is perfectly valid: function foo() : string {
$someVar = SomeValueType::fromSomeInput(...);
return (string) $someVar;
} So far, so good, but then over time the code is changed: function foo() : string {
$someVar = SomeValueType::fromSomeInput(...);
if (condition()) {
$someVar = null;
}
return (string) $someVar;
} Is the second example still valid? Maybe, but the implicit cast obfuscated it, and prevented static analysis from picking up the null pointer exception. To recap: I avoid language casts as a way to downcast value types, and instead suggest having the cast as an explicit non-magic method on the value type. EDIT: for the sake of clarity, I'm adding another equivalent example, showing that this has to do with long-term stability, rather than bugs in a single block of code.Consider following function someValue() : SomeValueType
{
return SomeValueType::fromSomeInput(...);
} We can have two consumers function foo() : string
{
return (string) someValue();
}
function bar() : string
{
return someValue()->toString();
} Should function someValue() : ?SomeValueType
{
if (condition()) {
return null;
}
return SomeValueType::fromSomeInput(...);
} Now we have By using |
@Ocramius, and why do you prefer to use static method for creating object instead of using |
I go with named constructors for anything that represents data, because you can only have one For example:
I also make |
Mhmm i’d go with factories for that. |
A static method that produces an instance is a factory function. Moving it to a separate class has no technical advantage, and reduces discoverability. |
@kaystrobach @Ocramius and forces |
…n 4.0.0" This reverts commit 4c467ce. For more information, please see the discussion at: 4c467ce#commitcomment-31174263 Also refer to the discussion at: ShittySoft/symfony-live-berlin-2018-doctrine-tutorial#3 (comment) TL;DR: I am retaining `toString()` for improved static analysis and long-term stability.
as using casting may lead to bugs as described here ShittySoft/symfony-live-berlin-2018-doctrine-tutorial#3 (comment)
This patch introduces value objects into the mix.
What we did is isolating these concepts into these specific well-defined data structures, which would otherwise be
string
s, and therefore prone to a lot of errors:ClearTextPassword
- a password type, designed specifically to never be cast back tostring
in order to avoid obvious security issuesPasswordHash
EmailAddress
(which is also the concept of "identityfor our
User` object)