Это довольно старый вопрос, ответ на который уже был принят, но для уточнения предоставленного ответа и решения вопросов, которые возникли в разделе комментариев, этот дополнительный ответ предоставляется.
Как поставлено, вопрос немного неопределенен. Когда спрошено, должно ли что-то быть сделано определенным образом относительно разработки программного обеспечения, вопрос мог быть понят как вопрос относительно основных принципов проектирования, которые управляют рассматриваемой темой, когда такие принципы проектирования должны применяться, если не однородно, или оба , Чтобы помочь в объективном обсуждении темы, давайте рассмотрим эти два аспекта по очереди.
Конкретная практика создания конструктора для отображения значений из одного объекта в другой создает связь между двумя объектами. Модель представления содержит свойства и / или поведение, относящиеся к конкретному представлению в системе. Поскольку целью такого объекта является моделирование конкретного представления, инкапсуляция логики отображения для инициализации внутреннего состояния / значений модели из другого типа в системе означает, что модель представления теперь содержит код, который может потребоваться изменить по причинам кроме изменений в том, как моделируется представление. Такие изменения открывают возможность неблагоприятного влияния на другие аспекты поведения модели, что приводит к непреднамеренной регрессии в поведении системы. Принцип, регулирующий разделение компонентов в системе для предотвращения непреднамеренного регресса поведения путем объединения нескольких задач, называется принципом единой ответственности.
Вопрос о том, когда такие принципы должны применяться, немного сложнее. Важно помнить, что программное обеспечение, как правило, написано с определенной целью (например, решение некоторых бизнес-задач, содействие развлечению или обучению и т. Д.), И то, что лучше для любого данного компонента программного обеспечения, зависит от поставленной задачи. Выбор, сделанный для системы программного обеспечения, которая создается в качестве основного продукта для конкретной компании, может сильно отличаться от выбора, который был сделан для системы, разрабатываемой для решения насущной проблемы. Объем работ, требуемых для облегчения определенных типов развязки, также должен быть рассмотрен. Некоторые методы развязки относительно легко внедрить, в то время как другие могут быть более сложными и даже включают пошаговые кривые обучения для начальной реализации, а также для каждого нового разработчика, добавленного в команду, ответственную за обслуживание программного обеспечения. Несмотря на то, что ни одна эвристика не является идеальной для принятия таких решений, разработка, управляемая тестами, устанавливает эвристику, заключающуюся в том, чтобы не вводить абстракции до появления дублирования. Например, шаблон стратегии - это отличный метод для соблюдения принципа Open / Closed, принципа, регулирующего проектирование объектов, позволяющего применять их в различных сценариях без необходимости изменять существующий код. Однако, следуя методикам разработки, основанным на тестировании, не следует вводить шаблон стратегии, пока не будет соблюден второй вариант использования. Следуя этой эвристике, разработчики вынуждены ограничивать свои усилия для выполнения поставленной задачи, только написав код, необходимый для выполнения задачи без дублирования, что приводит к минимизации потерь и максимизации удобства обслуживания (посредством минимизации сложности).
Тем не менее, разработка программного обеспечения - это и наука, и искусство. Это наука в том смысле, что существуют правила, которые определяют, что можно и что нельзя делать для достижения определенных целей, но это также искусство, заключающееся в том, что вы становитесь лучше в этом, чем больше вы это делаете, и есть определенные компромиссы, которые нужно сделать. что в конечном итоге должно быть сделано субъективно. Например, как разработчик клиентского программного обеспечения, я, как правило, никогда не занимаюсь проектированием и разработкой приложений с коротким сроком службы. Таким образом, я не жду, пока не увижу дублирование, прежде чем внедрять в свои приложения внедрение зависимостей на основе соглашений. Введение согласованного использования внедрения зависимостей в приложении требует гораздо меньших затрат в начале жизненного цикла программной системы, чем ожидание, пока вы не почувствуете потребность в нем.
Что касается конкретного примера добавления кода отображения в моделях представления, хотя он и связывает модель представления с конкретной моделью предметной области, на практике я не считаю, что это является большой проблемой. Модель представления вряд ли будет использоваться с другими моделями предметной области, и тип вводимого кода (т. Е. Отображение) обычно не содержит бизнес-логики, поэтому вероятность такого нарушения SRP, вызывающего значительный регресс в системе, гораздо меньше, чем нарушение SRP на уровне приложений или доменов.
Тем не менее, я не считаю, что процесс добавления логики отображения в конструкторах может значительно сэкономить время. Если бы нужно было создать отдельный класс для инкапсуляции отображения между объектом домена и моделью представления в большинстве языков, мы говорим только о дополнительных нескольких строках кода. Вот разница в реализации:
// constructor
public ViewType(DomainType domainType) {
...
}
// mapper class
public class ViewTypeMapper {
public ViewType Map(DomainType domainType) {
...
}
}
Итак, вы либо возвращаете новый ViewType (domainType), либо вы возвращаете новый ViewTypeMapper (). Map (domainType). Я просто не вижу, где разделение в этом случае добавляет какую-либо значительную работу. В большинстве случаев вы уже потратили впустую время и деньги своей компании или клиента, даже поговорив об этом, потому что вы неизменно будете говорить об этом в течение более длительного периода времени, чем если бы вы просто создавали отдельные классы для представления сопоставления, или если вы хотите пойти дальше и просто настроить Automapper.