У меня есть сущность "Клиент" с несколькими свойствами, одним из которых является "countryCode". Когда код страны установлен, он должен быть проверен, если он действителен. Я мог бы использовать установщик Customer, чтобы выполнить эту проверку, но проблема в том, что существует таблица «страна», в которой хранятся доступные коды стран, и, насколько я знаю, считается плохим стилем, чтобы сделать сущность зависимой от любых репозиториев.
Я мог бы позволить службе выполнить проверку:
class CustomerUpdateService{
public function updateFromDto(Customer $customer, CustomerUpdateDto $updateDto): Customer
{
$countryCode = $updateDto->getCountryCode();
$country = $this->countryRepository->find($countryCode);
if (!isset($country){
throw new InvalidArgumentException('Unallowed country code ' . $countryCode);
}
$customer->setCountryCode($countryCode);
//update other properties
return $customer;
}
}
По моему мнению, объект не должен позволять устанавливать недопустимые состояния свойств, поэтому он должен сам выполнять проверку. Но как этого добиться, не создавая нежелательных зависимостей? Единственное, о чем я могу думать, это передать разрешенные страны установщику:
class Customer{
public function setCountryCode(string $countryCode, array $availableCountries){
$availableCountryCodes = [];
foreach ($availableCountries as $country){
$availableCountryCodes[] = $country->getCode();
}
if (!in_array($countryCode, $availableCountryCodes)){
throw new InvalidArgumentException('Unallowed country code ' . $countryCode);
}
$this->countryCode = $countryCode;
}
}
или передать CountryCodeValidator установщику:
class Customer{
public function setCountryCode(string $countryCode, CountryCodeValidator $validator){
$validator->validate($countryCode);
$this->countryCode = $countryCode;
}
}
Это законное решение? Есть ли лучшие подходы?