Еще один вопрос архитектуры приложения - PullRequest
3 голосов
/ 21 июля 2011

Я пытаюсь использовать DDD, и я постараюсь описать самым простым образом, что я сделал.

Основной проект
Основной проект содержит сущности, VO и доменные службы,Например, у меня есть Пользователь сущность и UserRelation сущность.Я думаю, что мы все знаем, что такое сущность Пользователь . UserRelation содержит информацию о том, как пользователи связаны друг с другом, например, следовать и подключаться (двунаправленное отслеживание).Из-за этого у меня есть UserDomainService с методами без сохранения состояния, такими как Follow (пользователь, пользователь) и Connect (пользователь, пользователь).

public class User
{
    public string Name { get; set; }
    public string Username { get; set; }

    public void ChangeUsername(stirng newUsername)
    {
        ApplyEvent(new UserUsernameChanged(newUsername));
    }
}

public class UserRelation
{
    ctor(User1, User2, isBidirectional)
    public User User1 { get; set; }
    public User User2 { get; set; }
    public bool IsBidirectional { get; set; }
}

public class UserDomainService
{
    public UserRelation Follow(User user1, User user2)
    { 
        return new UserRelation(user1,user2,false);
    }
}

Проект репозитория

Я использую NHibernate, поэтому я решил не создавать такой проект.Вместо этого я использую NHibernate напрямую.Например, в моем пользовательском интерфейсе я получаю объект пользователя из БД, изменяю его и затем вызываю session.Save (пользователь).

Проблема

Если я хочучтобы выполнить операцию, как следует, я делаю это:

  • Получить некоторую информацию из БД
  • Вызвать Follow (user1, user2) из ​​службы
  • Сохранить объект UserRelationв БД В конце код приложения становится немного сложным.Представьте себе, если мы хотим использовать этот код в 2-3 местах, и в какой-то момент нам нужно его реорганизовать.

Мое решение
Мое решение состоит в создании ApplicationServiceпроект, который сделает грязную работу и заставит потребителя использовать ApplicationService вместо того, чтобы напрямую использовать службы Entitties и Domain

public class UserApplicationService
{
    ctor(UserDomainService userDomainService){}

    User GetUser(Guid id)
    {
        return NhibernateSession.Get(id)
    }

    public void Follow(Guid user1Id, Guid user2Id)
    {
        var u1 = GetUser(user1Id);
        var u2 = GetUser(user2Id);
        var userRelation = _userDomainService.Follow(u1,u2);
        NhibernateSession.Save(userRelation);
    }

    public void ChangeUsername(Guid user, string newUsername)
    {
        user.ChangeUsername(newUsername);
        NhibernateSession.Save(user);
    }
}

Является ли этот сервис приложений хорошим или плохим?Как вы можете видеть, новый сервис действует также как репозиторий, поэтому мы можем создать класс UserRepository, но пока пропустим это.Что меня беспокоит, так это параметры двух методов.Они принимают Guids, а сервис извлекает пользователей из БД.Другой вариант - передать непосредственно объект User.Метод ChangeUsername похож на метод из сущности пользователя + постоянство.

Ну, что вы думаете по этому поводу?

Ответы [ 2 ]

1 голос
/ 21 июля 2011

Мои 2 цента.

DDD применимо и имеет смысл для больших проектов. Вы не должны применять его к проектам только потому, что это круто . Глядя на NHibernateSession, я вижу, что вы можете получить пользователя по идентификатору. Хорошо, если NHibernateSession отвечает за то, какие другие доменные объекты у вас есть? У вас нет хранилища, почему вы применяете перегрев DDD?

Хорошо, продолжайте, если у вас большой домен, мне не понятно, зачем вам создавать новый проект для размещения Follow функциональности (в этом нет ничего плохого во входных GUID). Слой IMO Application Service не должен иметь дело с сущностями и инфраструктурой, так как для этого парня он кажется слишком низким уровнем. Уровень обслуживания приложений отвечает за все приложение, а не за функциональность некоторых объектов домена. Я заметил, что у вас есть _userDomainService, который кажется более уместным в вашем случае. Если переместить функциональность Follow там не имеет особого смысла, я бы создал другую службу на уровне Domain Services, назвав ее что-то вроде UsersManagerService или UsersDomainService

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

1 голос
/ 21 июля 2011

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

...