2016-08-01 6 views
5

Я был очень занят, пытаясь понять понятия слоя ddd и Model в последнее время. Читайте тонны статей, примеры, Q и A, потратили на это много часов. И все же я не уверен, правильно ли я получил некоторые принципы.DDD, PHP. Объект домена и бизнес-логика

Один из них - ответ на вопрос: сколько бизнес-логики должно существовать в объектах Domain? Некоторые источники говорят, что объекты домена должны быть привязаны ко всей бизнес-логике, с другой стороны, я столкнулся с статьями, где, как я предполагал, он должен быть как можно более крошечным и представлять только его значения. Это меня смущает.

В моем понимании объекты домена являются классами, которые представляют собой сущности в домене.

Итак, давайте, например, перейдем к объекту-фактуре. Каждый счет-фактура состоит из его элементов. Для расчета стоимости счета-фактуры, мы должны суммировать все значения предметов (это очень простой пример, в реальном мире был бы случаи, такими как добавление налога, вычислительным оплачиваемой стоимость и т.д.)

class Invoice 
{ 
    public $id; 
    public $items = []; 
    public $status; 

    const STATUS_PAID = 'paid'; 
    const STATUS_NOT_PAID = 'not_paid'; 

    public function isPaid() 
    { 
     return $this->status == self::STATUS_PAID; 
    } 

    public function getInvoiceValue() 
    { 
     $sum = 0; 
     foreach($this->items as $item) { 
      $sum += $item->value; 
     } 
     return $sum; 
    } 
} 

В моем понимании, метод isPaid() находится в нужном месте. Это относится к его собственным данным. Но я не уверен в getInvoiceValue(). Мы работаем здесь на других объектах домена.

Возможно, нам нужно использовать объекты домена только для представления данных, но использовать некоторые декораторы для выполнения более сложных задач?

Заранее благодарен.

ответ

2

Сколько бизнес-логики должно существовать в объектах Domain?

Все это (если возможно). Точка DDD - это захват вашей бизнес-логики в вашем домене - здесь могут использоваться различные тактические шаблоны (Агрегаты, объекты, объекты ценности, службы домена и т. Д.).

Объекты домена - это классы, которые представляют собой объекты в домене.

Классы в вашем домене могут представлять больше, чем просто объекты. Агрегаты, объекты, объекты ценности, доменные службы и т. Д. Могут быть представлены классами в вашем домене.

Но я не уверен в getInvoiceValue(). Мы работаем здесь на других объектах домена.

Пример, который вы даете из счета-фактуры, является классическим примером агрегирования - счета-фактуры, который содержит InvoiceItems. getInvoiceValue() здесь отлично.

В нашем случае счет-фактура является агрегатом. Агрегатный корень - это сам Счет-фактура, но это тоже Сущность, правильно? Он имеет свою собственную идентификацию (номер счета-фактуры, который является уникальным).

Да правильно

Что InvoiceItems тогда? Могу ли я получить их непосредственно из репозитория InvoiceItem (если я должен его создать), или мне всегда приходится работать только на Aggregate?

Это зависит от вашего прецедента. Это помогает разделить модели записи и чтения (CQRS). Если вы говорите о стороне чтения (т. Е. Отчетности), вы обходите модель домена и имеете объекты, которые представляют вашу модель чтения. Это может быть просто запрос к базе данных. Если вы говорите о своей стороне записи (т. Е. О командах, домене), то обычно вы должны иметь репозиторий на каждый корень заполнителя. Каковы ваши общие корни - это вопрос моделирования. Вы хотите создать их таким образом, чтобы они применяли все ваши бизнес-правила - в вашем примере, если Счету необходимо загрузить InvoiceItems для обеспечения соблюдения правил (например, «не более 5 штук на счет-фактуру»), то да, они должны быть загруженный через корень заполнителя

+0

Благодарим вас за полезный ответ. Итак - давайте подтвердим правильность моего понимания. В нашем случае счет-фактура является совокупностью. Агрегатный корень - это сам Счет-фактура, но это тоже Сущность, правильно? Он имеет свою собственную идентификацию (номер счета-фактуры, который является уникальным). Что такое InvoiceItems? Могу ли я получить их непосредственно из репозитория InvoiceItem (если я должен его создать), или мне всегда приходится работать только на Aggregate? – hopsey

+0

обновил мой ответ – tomliversidge

3

Я не уверен, есть ли справа ответ на этот вопрос, потому что применение DDD действительно зависит от конкретного домена, к которому вы его применяете. Есть места, где ваша реализация может быть абсолютно эффективной, если она удовлетворяет потребности бизнеса. В других, как вы упомянули с налогами и т. П., Это не так. Поэтому я бы сказал, что вам нужно постоянно задавать вопросы о своем домене, чтобы полностью понять, каковы ваши потребности, прежде чем переводить их в код.

Сказав, что если у вас более сложный сценарий, требующий дополнительных знаний о внешнем мире, чтобы придумать стоимость счета-фактуры, один из вариантов должен был бы явно представлять это в вашем домене. В вашем примере, что может быть InvoiceProducer, которые могли бы иметь подпись, как:

class InvoiceProducer { 

    public function __construct(TaxProvider $taxProvider) { 
     $this->taxProvider = $taxProvider; 
    } 

    public function invoiceFor(array $items) { 
     new Invoice($items, $this->calculateValue($items)); 
    } 

    private function calculateValue(array $items) { 
     $sum = array_reduce($items, function($acc, $item){ 
      $acc += $item->value; 
     } 

     return $this->taxProvider->applyTaxTo($sum); 
    } 
} 

Другим вариантом было бы использовать какой-то шаблон стратегии, который оставил бы свою реализацию очень похоже на то, как это сейчас, но вы бы пройти с вызовом, как вы хотите налогообложение исчисляются:

public function getInvoiceValue(TaxProvider $taxProvider) 
{ 
    $sum = 0; 
    foreach($this->items as $item) { 
     $sum += $item->value; 
    } 

    return $taxProvider->applyTaxFor($sum); 
} 

Опять же, это зависит от того, как ваших конкретных работ домена, но, как вы можете видеть, осуществление не должно быть большой сделки. Больше о том, как все это подходит в вашем домене.

3

Сколько должна существовать бизнес-логика в объектах Domain? [...] Я столкнулся с статьями, где, как я полагал, он должен быть как можно меньше и представлять только его ценности.

Остерегайтесь Anemic Domain Model, которые почти исключительно состоят из данных и не имеют поведения. DDD - это создание модели домена, богатой поведением. Таким образом, добавить логику в классы домена.

DDD подчеркивает хороший объектно-ориентированный дизайн, методы и данные вместе, тем самым способствуя высокому cohesive systems.

+0

благодарю вас за ответ. Если мы присоединим много бизнес-логики к одному доменному объекту, не противоречит ли он SRP? – hopsey

+0

DDD хочет включить хороший дизайн OO. Следите за принципом единой ответственности и другими разумными практиками ОО. –

+1

@hopsey Просто помните, что ваш домен больше, чем просто объекты домена. Бизнес-логика не ограничивается только существующими в совокупных корнях и сущностях. Они могут жить в нескольких местах, включая сервисы домена, команды и т. Д. Домен представляет собой сплоченную коллекцию классов, представляющих вездесущий язык. Нет правила, из-за отсутствия лучшего слова, в котором говорится, что бизнес-правило должно жить в совокупности/сущности и нигде больше.Хорошая часть этого будет доведена до ваших конкретных решений по внедрению и разработке. –

 Смежные вопросы

  • Нет связанных вопросов^_^