Подтвердить что ты не робот

Каков практический способ моделирования таблиц поиска в Domain Driven Design (DDD)?

Я просто изучаю DDD (книга Эрика Эванса открыта передо мной), и я столкнулся с проблемой, на которую я не могу найти ответ. Что вы делаете в DDD, когда пытаетесь получить простой список записей поиска?

Исх.

EmployeeID: 123
EmployeeName: John Doe
Штат: Аляска (выпадающий)
Графство: Wasilla (выпадающее меню - будет отфильтровано в зависимости от состояния).

Например, скажем, что у вас есть объект домена Employee, интерфейс IEmployeeRepository и класс EmployeeRepository. Это будет использоваться пользовательским интерфейсом для отображения списка сотрудников и отдельных деталей. В пользовательском интерфейсе вы хотите использовать раскрывающийся список для штата и округа, где живет сотрудник. Доступные округа будут отфильтрованы в зависимости от выбранного состояния.

К сожалению, таблицы базы данных и пользовательский интерфейс выглядят совсем по-другому. В tblEmployees он содержит код штата = AK и код округа = 02130, а не имена штата и округа.

Старый способ (до того, как я начал этот квест DDD) был бы довольно простым, просто создайте 2 запроса и используйте DataReader для заполнения раскрывающихся списков. Под дисплеем в раскрывающихся списках отображается значение, которое автоматически используется в сообщениях формы.

С DDD, однако, я не уверен, как вы должны это делать. Сначала я начал с создания объектов State и County, а также репозиториев и интерфейсов для репозиториев. Тем не менее, запись 4 классов + 2 интерфейса и сантехника в файлах hbm.xml + Объекты Employee Business кажутся излишними для всего 2 запросов для 2 выпадающих списков. Должен быть лучший способ, не так ли? Я не буду менять записи в таблицах штата или графства в ближайшее время, и даже если бы я это сделал, это не было бы через это приложение. Поэтому я не хочу создавать бизнес-объекты для штата и округа, если мне это не нужно.

Самое простое решение, которое я вижу, - просто создать вспомогательный класс с методами, которые возвращают словари, такие как GetStatesAll(), GetState() и GetCounties() и GetCounty(), но это просто неправильно с точки зрения DDD.

Пожалуйста, помогите. Как я могу использовать DDD без перепрограммирования всего лишь нескольких простых поисков?

Окончательное решение Я думаю, что, наконец, нашел свой ответ на основе опыта, который должен был поместить метод GetStates() в свой собственный класс доступа к данным, но не в класс репозитория. Поскольку я только делал доступ только для чтения, я бросил его в структуру DTO. Поскольку база данных была небольшой, я бросил их полностью в один класс, например, описанный ниже.

Мои выводы:

  • Таблицы поиска НИКОГДА не относятся к объектам, потому что таблицы поиска ВСЕГДА имеют идентификатор. Если бы у них не было удостоверения личности, у вас были бы дубликаты, что бы не имело большого смысла.
  • В таблице поиска только для чтения может быть репозиторий, но, вероятно, он не нужен. Целью репозитория является сокращение сложности путем принудительного доступа только через совокупность. Прохождение через совокупность дает вам возможность обеспечить соблюдение бизнес-правил, например, не добавлять шины, если у вас нет автомобиля.
  • Если вы разрешаете обслуживание CRUD в таблице поиска, тогда для таблицы поиска имеет смысл иметь собственный репозиторий.
  • Тот факт, что я в конечном итоге сохранил коды как структуры, не делает их "типами значений". Фаулер говорит в POEAA, что структура - это тип значения. Это правда, структуры неизменны, поэтому Фаулер говорит, что они "типы ценности", однако я использовал их по-разному. Я использовал структуры как легкий способ передать DTO, которые я никогда не планировал изменять после их первоначального создания. По правде говоря, структуры, которые я использовал, действительно имели идентификаторы, но поскольку они были только для чтения, они работали как структуры.
  • Один шаблон, который я использовал, которого я не вижу в другом месте, заключается в том, чтобы сделать поля первичного ключа неизменными. Они заданы конструктором, но они доступны только для чтения (а не для частных accessors) и не могут быть изменены после создания объекта.
4b9b3361

Ответ 1

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

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

Ответ 2

Использование DDD У меня есть нечто похожее на следующее:

interface IAddressService
{
  IList<Country> GetCountries ();
  IList<State> GetStatesByCountry (string country);
  IList<City> GetCitiesByState (string state);
  // snip
}

Страна, государство и город - это объекты ценности, которые поступают из таблицы поиска в базе данных.

Ответ 3

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

Ответ 4

Вы читаете неправильную книгу, если хотите узнать, как делать DDD, не усложняя ее.: -)

Самое простое решение, которое вы предлагаете, прекрасно, если оно соответствует вашим потребностям. Инкапсулирование адресных данных в бизнес-объектах может быть таким же простым или сложным, как требует ваше приложение. Например, объект State имеет отношения "один ко многим" с округом, поэтому Employee действительно просто нужно ссылаться на графство, если вы решили его моделировать. Я бы представил только такую ​​сложность, если это необходимо.

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

Ответ 5

Хорошо, я прочитал статью Mathias Verraes некоторое время назад об этом . Он говорит о разделении объектов ценности в модели из понятий, которые обслуживают пользовательский интерфейс.

Цитата из статьи, когда ее спрашивают, следует ли моделировать страны как объекты или объект ценности:

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

Он предложил другой подход, чтобы ввести новое понятие под названием AvailableCountry:

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

<?php

final class Country
{
    private $countryCode;

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

    public function __toString()
    {
        return $this->countryCode;
    }
}

final class AvailableCountry
{
    private $country;
    private $name;

    public function __construct(Country $country, $name)
    {
        $this->country = $country;
        $this->name = $name;
    }

    /** @return Country */
    public function getCountry()
    {
        return $this->country;
    }

    public function getName()
    {
        return $this->name;
    }

}

final class AvailableCountryRepository
{
    /** @return AvailableCountry[] */
    public function findAll()
    {
        return [
            'BE' => new AvailableCountry(new Country('BE'), 'Belgium'),
            'FR' => new AvailableCountry(new Country('FR'), 'France'),
            //...
        ];
    }

    /** @return AvailableCountry */
    public function findByCountry(Country $country)
    {
        return $this->findAll()[(string) $country];
    }
}

Итак, кажется, что есть 3-е решение, которое должно моделировать таблицы поиска как объекты и сущности значения.

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