Бизнес-логика и правила - как отделить их от модели предметной области - PullRequest
0 голосов
/ 31 мая 2018

У меня небольшие проблемы с выяснением, как сделать мой дизайн слабо связанным.В частности, как внедрить бизнес-логику и правила в модели предметной области, а также где разместить различные части кода - то есть структуру папок.

Чтобы пояснить, как я понимаю термины:
Бизнеслогика: решение проблем, связанных с доменом.
бизнес-правила: правила, специфичные для домена.
модель домена: абстракции объектов, относящихся к домену, объектов реального мира, например сотрудника.

Итак, давайте сделаем простой пример

Допустим, у нас есть компания с сотрудниками.Каждый сотрудник должен иметь защитный номер (бизнес-логика).Номер безопасности должен быть не менее 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;
    }
}


Я вижу некоторые проблемы с этим подходом ...

  1. Установка номера защиты требует, чтобы вы передавали объект вдоль самого номера защиты.Что, на мой взгляд, выглядит несколько неприятно для сеттера.
  2. Объекты сотрудника могут быть оставлены в недопустимом состоянии из-за возможности их создания без указания номера защиты.

Чтобы решить вторую проблему, я могу просто создать конструктор для класса Employee, как показано ниже

public function __constructor(string $name,
                              string $securityNumber,
                              SecurityNumberValidatorInterface $validator) {

    $this->name = $name;
    $this->setSecurityNumber($securityNumber, $validator);
}


Это может быть антипаттерном из-за вызова сеттера вконструктор ...
Какой подход к этому лучше?Было бы вообще удалить валидатор из модели Employee и вместо этого пойти на фабрику или фасад?

Ответы [ 2 ]

0 голосов
/ 31 мая 2019

Существует объект значения вызова пути, который является частью сущности.В этом случае вы можете заключить защитный номер в класс (который является объектом значения), вызывая SecurityNumber, и добавить туда проверку.Вы можете сослаться на этот пример: https://kacper.gunia.me/ddd-building-blocks-in-php-value-object/

В DDD есть вызов анти-паттерна Primitive Obsession, ваш разум может быть глубоко в этой ловушке.

0 голосов
/ 10 июня 2018

Поскольку «каждый сотрудник должен иметь защитный номер», является бизнес-логикой для вас, определение Employee, не зависящее от бизнеса, не будет включать свойство securityNumber, поскольку сотрудники, не входящие в этот бизнес, могут не иметь защитных номеров.Вместо этого вы должны написать бизнес-класс BusinessNameEmployee, который расширяет сотрудника и в качестве свойства этого класса будет иметь защитный номер.При желании вы можете рассмотреть возможность использования интерфейса IEmployee вместо класса Employee.Ваш класс BusinessRules (который будет содержать валидатор длины) затем может быть передан в конструктор для BusinessNameEmployee.

...