DDD: соглашение о пространстве имен доменных имен

Я пишу приложение с моделью домена в PHP, и мне интересно, какое соглашение об именах я должен принять.

Скажем, у меня есть Customer, имеющий Address внутри своего сводного корня.
У меня также есть Product, имеющий Option внутри своего сводного корня.

У меня есть две альтернативы:

  • Держите агрегатные корни в корне модели домена:

    Customer
    Customer\Address
    Product
    Product\Option
    

    Pro: я могу использовать как Customer, так и Product в том же пространстве имен
    Кон: Customer должен ссылаться на свой собственный Address как Customer\Address

  • Группируйте все агрегатные классы в одном и том же пространстве имен, включая корень агрегата:

    Customer\Customer
    Customer\Address
    Product\Product
    Product\Option
    

    Pro: Customer может ссылаться на свой адрес как Address
    Кон: из моего пространства имен корневых доменов я должен ссылаться:

    • Customer как Customer\Customer
    • Product как Product\Product

Ответ 1

Я написал небольшую структуру некоторое время назад, и я решил использовать первое предлагаемое вами решение.

Держите агрегатные корни в корне модели домена:

Почему?

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


Посмотрите, как настроить ваши классы с помощью решения n ° 2

Customer\Customer
Customer\Address

Вам нужно будет написать:

$customer = new Customer\Customer();
$address = new Customer\Address();

Вы можете видеть право повторения? Это не похоже на меня. По-моему, это нравится писать

$customer->getCustomerId();

Зачем повторять Заказчик в имени метода? Мы знаем это идентификатор клиента, так как мы используем объект Customer.

Еще одна "плохая вещь" с этой моделью - невозможность использования зарезервированного ключевого слова в качестве имени класса.

Например, используя соглашение груши, вы могли бы иметь класс

Customer_Abstract

Расположен на Customer/Abstract.php, который подходит мне, но если вы попытаетесь перевести его с помощью пространства имен, у вас будет

namespace Customer;

class Abstract {}

что приводит к фатальной ошибке. Поэтому вам снова придется повторять домен в имени класса:

namespace Customer;

class AbstractCustomer {}

$customer = new Customer\AbstractCustomer();

Теперь посмотрим, как настроить ваши классы с помощью решения n ° 1

Customer
Customer\Address

Вы напишете:

$customer = new Customer();
$address = new Customer\Address();

Нам больше не нужно повторять заказчик дважды, чтобы стимулировать класс Customer. Однако по-прежнему ясно, что адрес связан с клиентом.

Вот почему я решил использовать эту модель.

EDIT: Zend Framework 2 также использует это соглашение