Как должен добавление совокупного корня в репозиторий быть выраженным?

Скажем, у нас есть совокупный корневой объект Порядка типа, который связывает строки порядка и клиенты. Когда я думаю об объекте порядка, более естественно осмыслять его как не определяемый без идентификатора. Порядок без идентификатора, кажется, лучше представлен как запрос порядка, чем порядок.

Для добавления порядка к репозиторию я обычно вижу, что люди инстанцируют порядка без идентификатора и затем имеют репозиторий, завершенный объект:

class OrderRepository
{
    void Add(Order order)
    {
        // Insert order into db and populate Id of new order
    }
}

То, что мне нравится приблизительно этот подход, - то, что Вы добавляете экземпляр Порядка к OrderRepository. Это имеет большой смысл. Однако экземпляр порядка не имеет идентификатора, и в объеме потребителя репозитория, он все еще не имеет никакого смысла мне, что порядок не имеет идентификатора. Я мог определить OrderRequest, чтобы быть экземпляром порядка и добавить, что в репозиторий, но это испытывает желание получать яблоко из апельсина и затем добавлять его к списку апельсинов.

С другой стороны, я также видел этот подход:

class OrderRepository
{
    Order AddOrder(Customer customer)
        // It might be better to call this CreateOrder
    {
        // Insert record into db and return a new instance of Order
    }
}

То, что мне нравится приблизительно этот подход, - то, что порядок не определен без идентификатора. Репозиторий может создать запись базы данных и собрать все обязательные поля прежде, чем создать и возвратить экземпляр порядка. Какие запахи здесь то, что Вы никогда на самом деле добавляете экземпляр порядка в репозиторий.

Так или иначе работы, таким образом, мой вопрос: я должен жить с одной из этих двух интерпретаций, или существует ли лучшая практика для моделирования вставки?

Я нашел этот ответ, который подобен, но для объектов значения: как я должен добавить объект в набор, сохраняемый совокупным корнем. Когда дело доходит до объекта значения нет никакого беспорядка, но мой вопрос касается объекта идентификационными данными, полученными из внешнего источника (Автоматически сгенерированный идентификатор Базы данных).

5
задан Community 23 May 2017 в 12:21
поделиться

1 ответ

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

Остальные параметры зависят от логики домена. Если логика домена определяет, что порядок без идентификатора не имеет смысла, идентификатор является обязательным инвариантным порядком, и мы должны моделировать его так:

public class Order
{
    private readonly int id;

    public Order(int id)
    {
        // consider a Guard Clause here if you have constraints on the ID
        this.id = id;
    }
}

Обратите внимание, что, путем размещения поля как Readonly Мы сделали это инвариантным. Нет никакого способа изменить его для данного экземпляра порядка. Это идеально подходит с дизайном доменов объект .

Вы можете дополнительно привести к обеспечению логике домена, поместив охранник в конструктор, чтобы идентификатор был отрицательным или ноль.

К настоящему времени вам, вероятно, вам интересно, как это, возможно, будет работать с автоматически сгенерированными идентификаторами из базы данных. Ну, это не так.

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

Это оставляет вас двумя вариантами:

  • Измените идентификатор в GUID. Это позволяет любому абоненту поставлять уникальный идентификатор для нового заказа. Однако это требует, чтобы вы также использовали GUID в качестве клавиш баз данных.
  • Измените API, чтобы создание нового порядка не принимает объект заказа, а скорее представилось о заказе, - заказа может быть почти идентична классу заказа, минус ID.

Во многих случаях создание нового порядка является бизнес-операция, которая нуждается в конкретном моделировании в любом случае, поэтому я не вижу проблем с этим различием. Хотя порядок и заказ могут быть семантически очень похожими, они даже не должны быть связаны в иерархии типа.

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

Если этот подход принят, метод дополнения должен возвращать экземпляр заказа (или, по меньшей мере, идентификатор), потому что в противном случае мы не можем знать идентификатор того, что мы только что создали. Это приводит нас к нарушению CQS, поэтому я склонен к , предпочитаю GUID для идентификаторов объектов .

5
ответ дан 14 December 2019 в 19:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: