У меня небольшие проблемы с выяснением, как сделать мой дизайн слабо связанным.В частности, как внедрить бизнес-логику и правила в модели предметной области, а также где разместить различные части кода - то есть структуру папок.
Чтобы пояснить, как я понимаю термины:
Бизнеслогика: решение проблем, связанных с доменом.
бизнес-правила: правила, специфичные для домена.
модель домена: абстракции объектов, относящихся к домену, объектов реального мира, например сотрудника.
Итак, давайте сделаем простой пример
Допустим, у нас есть компания с сотрудниками.Каждый сотрудник должен иметь защитный номер (бизнес-логика).Номер безопасности должен быть не менее 10 символов (бизнес-правило).
Мой выстрел в моделировании это будет выглядеть примерно так:
# Conceptual model of an employee within the company
class Employee {
private $name;
private $securityNumber;
// Business logic
public function setSecurityNumber(string $securityNumber,
SecurityNumberValidatorInterface $validator) {
if($validator->validateSecurityNumber($securityNumber)) {
$this->securityNumber = $securityNumber;
} else {
throw new \Execption("Invalid security number");
}
}
}
# Setup interface that corresponds to the business logic
interface SecurityNumberValidatorInterface {
public function validateSecurityNumber(string $validateThisSecurityNumber) : bool;
}
# Time to implement the business logic that is compliant with the rule
class SecurityNumberValidator implements SecurityNumberValidatorInterface {
public function validateSecurityNumber(string $validateThisSecurityNumber) : bool {
$valid = false; // control variable - ensuring we only need a single return statement
$length = strlen($validateThisSecurityNumber);
if ($length < 10) {
$valid = true;
}
return $valid;
}
}
Я вижу некоторые проблемы с этим подходом ...
- Установка номера защиты требует, чтобы вы передавали объект вдоль самого номера защиты.Что, на мой взгляд, выглядит несколько неприятно для сеттера.
- Объекты сотрудника могут быть оставлены в недопустимом состоянии из-за возможности их создания без указания номера защиты.
Чтобы решить вторую проблему, я могу просто создать конструктор для класса Employee
, как показано ниже
public function __constructor(string $name,
string $securityNumber,
SecurityNumberValidatorInterface $validator) {
$this->name = $name;
$this->setSecurityNumber($securityNumber, $validator);
}
Это может быть антипаттерном из-за вызова сеттера вконструктор ...
Какой подход к этому лучше?Было бы вообще удалить валидатор из модели Employee
и вместо этого пойти на фабрику или фасад?