В подходе DDD этот пример смоделирован правильно?

Просто созданный acc на ТАК для выяснения у этого :)

Принятие этого упрощенного примера: создание веб-приложения для управления проектами...
Приложение имеет следующие требования/правила.

1) Пользователи должны смочь создать проекты, вставляющие название проекта.
2) Названия проекта не могут быть пустыми.
3) Два проекта не могут иметь того же имени.

Я использую 4 многоуровневых архитектуры (Пользовательский интерфейс, Приложение, Домен, Инфраструктура).
На моем Прикладном уровне у меня есть следующий класс ProjectService.cs:

public class ProjectService
{
    private IProjectRepository ProjectRepo { get; set; }

    public ProjectService(IProjectRepository projectRepo)
    {
        ProjectRepo = projectRepo;
    }

    public void CreateNewProject(string name)
    {
        IList<Project> projects = ProjectRepo.GetProjectsByName(name);
        if (projects.Count > 0) throw new Exception("Project name already exists.");

        Project project = new Project(name);
        ProjectRepo.InsertProject(project);
    }
}

На моем Доменном Слое у меня есть класс Project.cs и интерфейс IProjectRepository.cs:

public class Project
{
    public int ProjectID { get; private set; }
    public string Name { get; private set; }

    public Project(string name)
    {
        ValidateName(name);
        Name = name;
    }

    private void ValidateName(string name)
    {
        if (name == null || name.Equals(string.Empty))
        {
            throw new Exception("Project name cannot be empty or null.");
        }
    }
}




public interface IProjectRepository
{
    void InsertProject(Project project);
    IList<Project> GetProjectsByName(string projectName);
}

На моем Уровне инфраструктуры у меня есть реализация IProjectRepository, который делает фактические запросы (код не важен).


Мне не нравятся две вещи об этом дизайне:

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

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

Так, мой вопрос с точки зрения DDD, это смоделировано правильно, или Вы сделали бы это по-другому?

10
задан Tag 3 April 2010 в 12:49
поделиться

2 ответа

Я думаю, что отчасти путаница с (1) заключается в том, что вам не хватает уровня - вставьте уровень сервиса в свою архитектуру, и ваша проблема исчезнет, ​​как по волшебству. Вы можете поместить сервис и реализацию репозитория на уровень сервиса, т. Е. У вас есть сервис, который использует конкретную реализацию репозитория. Другие службы могут выбрать альтернативную реализацию репозитория, если захотят. Ваше приложение может свободно выбирать любой интерфейс службы, который ему нравится. Сказав это, я не уверен, что в большинстве случаев это действительно имеет значение. Почти во всех моих приложениях есть один «домен / уровень данных», который в основном исправлен. Я могу наложить на него репозиторий или нет, в зависимости от сложности бизнес-логики. То же и с сервисом - он может просто не понадобиться, если проект не очень сложный. Если позже станет так, я всегда смогу провести рефакторинг. Обычно я помещал свой репозиторий в тот же проект, что и мой контекст данных (с использованием LINQ), и, если бы была служба, она была бы в отдельном проекте (потому что обычно она также была бы представлена ​​как веб-служба).

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

1
ответ дан 4 December 2019 в 04:21
поделиться

Процесс создания нового проекта включает две проверки (не нулевые и не повторяющиеся). В моем вышеупомянутом дизайне эти две проверки разбросаны в двух разных местах, что затрудняет (imho), что происходит.

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

Есть много видов подтверждения. И не может быть универсального механизма проверки . DDD просто говорит, что вы должны включить проверку домена в модель домена.

2
ответ дан 4 December 2019 в 04:21
поделиться
Другие вопросы по тегам:

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