Может ли «богатая модель предметной области» нарушать принцип единой ответственности?

Интересная ветка всплыла, когда я только что набрал этот вопрос. Хотя я не думаю, что это отвечает на мой вопрос.

Я много работал с.NET MVC3, где желательно иметь анемичную модель. Модели просмотра и модели редактирования лучше всего использовать в качестве простых контейнеров данных, которые вы можете просто передать из контроллера в представление. Любой поток приложений должен исходить от контроллеров, а представления обрабатывают проблемы пользовательского интерфейса. В MVC нам не нужно какое-либо поведение в модели.

Однако нам также не нужна какая-либо бизнес-логика в контроллерах. Для больших приложений лучше всего держать код предметной области отдельно и независимо от моделей, представлений и контроллеров (и HTTP в целом, если на то пошло ). Таким образом, существует отдельный проект, который прежде всего предоставляет модель предметной области (с сущностями и объектами-значениями, объединенными в агрегаты в соответствии с DDD ).

Я предпринял несколько попыток перейти от анемичной модели к более богатой кодом предметной области, и я подумываю о том, чтобы сдаться. Мне кажется, что классы сущностей, которые содержат данные и поведение, нарушают SRP.

Возьмем, к примеру, один очень распространенный сценарий в Интернете — составление электронных писем. При каком-то событии ответственность за создание объекта EmailMessage с учетом EmailTemplate, EmailAddress и пользовательских значений лежит на домене. Шаблон существует как объект со свойствами, а пользовательские значения вводятся пользователем. Давайте также скажем в качестве аргумента, что адрес FROM сообщения электронной почты может быть предоставлен внешней службой (IConfigurationManager.DefaultFromMailAddress ). Учитывая эти требования,кажется, что модель расширенной предметной области может возложить на EmailTemplate ответственность за составление сообщения электронной почты :

public class EmailTemplate
{
    public EmailMessage ComposeMessageTo(EmailAddress to, 
        IDictionary customValues, IConfigurationManager config)
    {
        var emailMessage = new EmailMessage(); // internal constructor
                                            // extension method
        emailMessage.Body = this.BodyFormat.ApplyCustomValues(customValues);
        emailMessage.From = this.From ?? config.DefaultFromMailAddress;
        // bla bla bla
        return emailMessage;
    }
}

. Это была одна из моих попыток создать модель богатой предметной области. Однако после добавления этого метода в обязанности шаблона EmailTemplate входило как содержание свойств данных сущности, так и составление сообщений. Это было около 15 строк и, казалось, отвлекало класс от того, что на самом деле означает быть EmailTemplate --, который, IMO, должен просто хранить данные (формат темы, формат тела, вложения и, необязательно, от / ответ. -на адреса ).

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

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