Say I have a CreateUser command:
class CreateUser
{
public string $email;
public string $password;
public string $firstName;
public string $lastName;
public LocalDate $dateOfBirth;
public ?string $location;
}
Is it OK if my User model accepts this command as a constructor parameter?
i.e. instead of having this:
class User
{
public function __construct(
string $email,
string $password,
string $firstName,
string $lastName,
LocalDate $dateOfBirth,
?string $location
) {
...
and have the command handler map the command data to the model(s), I could just simply make the model constructors accept the command as a parameter and extract the data they need:
class User
{
public function __construct(CreateUser $command)
{
...
}
Is this a correct approach, or are there drawbacks?
Small drawbacks.
Drawback #1 - you've added a (small) extra step of work. If I want a User, I first have to get a CreateUser command. So there's an extra step that gets in the way.
Drawback #2 - because you need a CreateUser, you need values for all of the fields of User and all of the extra fields that User doesn't care about.
For example, suppose you later decide that
CreateUsershould have a messageId. Now the code paths that want a User need to invent a messageId that they don't want in order to construct a CreateUser that they don't want so that they can construct the User that they do want.Wanting to have a function that accepts a CreateUser and returns a User is perfectly reasonable. It's even reasonable that you would want that function to be close to User.
You probably don't want that function to be __construct, though. A static helper method would probably be a healthier long term solution.