0

Я читал, что доступ к репозиторию из совокупного корня считается плохой практикой. Если, чем рассмотреть следующий пример:DDD: доступ к репозиторию из совокупного корня считается плохой практикой?

class User { 
    private String username; 
    public void changeUsername(String newUsrname) { 
    // How will I persist username to database if I don't have access to repository from aggregate root? 
    ... 
    } 
} 

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

Я вижу это так:

class User { 
    private String username; 
    private UserRepository userRepository; 
    public User(UserRepository userRepository) { 
     this.userRepository = userRepository; 
    } 

    public void changeUserName(String newUsername) { 
     this.username = newUserName; 
     userRepository.save(this); 
    } 
} 

Или я что-то пропустил в понятиях DDD?

+0

Ваш пример показывает ActiveRecord, а не DDD. – dit

+0

@dit, как бы вы это сделали в DDD? – Teimuraz

+0

проверить этот пример DDD: https://github.com/citerus/dddsample-core – dit

ответ

6

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

Текущая практика обычно обрабатывает ввод-вывод в компоненте приложения, а не в модели домена.

Application { 
    void when(ChangeUserName command) { 
     User user = this.userRepository.getUserById(command.userId); 
     user.changeName(command.name); 
     this.userRepository.save(user); 
    } 
} 

Рекомендованное чтение: Vladimir Khorikov по изоляции модели домена.

0

Просто продлить немного ответ дается @VoiceOfUnreason (что совершенно верно) здесь краткое объяснение о том, почему инъекционных репозиториях через конструктор, чтобы агрегировать корни не рекомендуется:

Хранилище должно зависеть от объекта, возвращается, а не наоборот. Причина этого в том, что ваш «объект домена» (подробнее об этом позже) может существовать (и должен быть проверен) без загрузки или сохранения (т. Е. Наличия зависимости от репозитория).

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

Эти концепции просто помогут вам создать код, который проще поддерживать, а также помогут вам применять лучшие практики, такие как SRP (принцип единой ответственности).

+0

В этом случае домен теперь не будет ничего об инфраструктуре, потому что я передаю только интерфейс репозитория, а интерфейс репозитория является частью домена. – Teimuraz

+0

Просто подумайте об модульном тесте класса User. Скажем, что для того, чтобы изменить имя пользователя, у вас есть некоторые инварианты, такие как он не может быть пустым и длиннее определенной длины и т. Д.Обеспечение инвариантов - это то, за что отвечает ваш пользовательский AR, но если вы также добавляете ответственность за сохранение, выборку и т. Д., Вы нарушаете SRP, что усложняет обслуживание класса AR плюс модульные тесты. – mgonzalezbaile