Я бы услышал, как вы peoploe карту доменных объектов с шаблоном отображения данных в doctrine2. Я просто столкнулся с проблемой, когда мои агрегаты используют чистый массив php и используют функции php, например, для работы с массивом array_shift. В любом случае это было хорошо, пока я не начал интегрировать сопоставления доктрин со своими предметными сущностями. Проблема была в том, как доктрина работает с ассоциациями между сущностями. Всякий раз, когда у моего совокупного корня была связь один ко многим (или любой другой tbh), доктрина использовала класс ArrayCollection вместо этого, вместо обычного массива. Я мог бы просто использовать один из методов, таких как toArray (), но мне нужно было бы сначала проверить в доменном объекте, является ли он классом коллекций доктрин, который будет грязным. Так или иначе, я решил сделать это в своем хранилище, прежде чем возвращать класс. Я сделал общедоступным свойство класса отражения и заменил его чистым массивом php. Работает менее грязно, но все же мне это не нравится. Поэтому мой вопрос в том, как вы, ребята, справляетесь с ограничениями доктрины или, может быть, для вас нет чего-то вроде ограничений :). И следующий вопрос, если вы, ребята, используете Doctrine ArrayCollection в ваших классах домена?
Для чего вы используете эти массивы?
Я подозреваю, что проблема в том, что вы используете массивы вместо объектов. Объекты должны отражать домен и предоставлять вам методы, которые существуют в домене. Если вы заменяете поведение в реальном мире массивами, вы на самом деле не следуете принципам DDD.
Простой пример:
/**
*
* @ORM\Table(name="sales_flat_order")
* @ORM\Entity(repositoryClass="Candle\OrderBundle\Repository\Mage\OrderRepository")
*/
class Order implements OrderInterface
{
/**
* @ORM\OneToMany(targetEntity="OrderItem", mappedBy="order", cascade={"persist"})
*
* @var OrderItem[]
*/
private $orderItems;
/**
* Constructor.
*/
public function __construct()
{
$this->orderItems = new ArrayCollection();
}
/**
* Check if all Items are marked as scanned
*
* @param integer $warehouseId Warehouse ID to check for.
*
* @return boolean
*/
public function isOrderScanCompleted($warehouseId)
{
foreach ($this->orderItems as $orderItem) {
if ($orderItem->getWarehouseId() == $warehouseId
&& !$orderItem->isScanComplete()) {
return FALSE;
}
}
return TRUE;
}
}
Я мог бы перебрать массив значений БД связанных OrderItems и проверить значения, которые составляют флаг «isScanComplete», но я решил реализовать его и таким образом инкапсулировать в классе OrderItem. Следовательно, нет необходимости в массиве значений.
В моих проектах я использую сущности доктрины (информация об отображении перемещается в файлы yml и находится вне домена) для этой цели.
В документации доктрины говорится, что:
Интерфейс Collection и класс ArrayCollection, как и все остальное в пространстве имен Doctrine, не являются ни частью ORM, ни DBAL, это простой PHP-класс, который не имеет внешних зависимостей, кроме зависимостей от самого PHP (и SPL). Поэтому использование этого класса в классах вашего домена и в других местах не создает связи с постоянным уровнем. Класс Collection, как и все остальное в пространстве имен Common, не является частью уровня постоянства. Вы даже можете скопировать этот класс в свой проект, если хотите удалить Doctrine из своего проекта, и все ваши доменные классы будут работать так же, как и раньше.
Так что можно использовать DoctrineCollection в домене, просто расширите его, чтобы легко заменить на случай, если вы перейдете на другую платформу / orm.
Также, пожалуйста, смотрите эти слайды https://www.slideshare.net/leopro/ Очистка архитектуры с СУСД-иерархического-в-PHP-35793127
Который относится к этому примеру приложения https://github.com/leopro/trip-planner
Возможно, вы захотите использовать файлы yml / xml для отображения информации схемы вместо аннотаций внутри объекта, чтобы также удалить эту зависимость из домена.
Этот вопрос был опубликован давно, но этот ответ может быть полезен другим пользователям.