Проект, над которым я сейчас работаю, требует большого количества страниц поиска / фильтрации. Например, у меня есть сложная страница поиска, чтобы получить проблемы по данным, категории, подразделению и т. д.
Класс предметной области является сложным и содержит множество объектов-значений и дочерних объектов.
. Мне интересно, как люди справляются с поиском / фильтрацией / отчетностью для пользовательского интерфейса. Насколько я знаю, у меня есть 3 варианта, но ни один из них не делает меня более счастливым.
1.) Отправьте параметры в репозиторий / DAO, чтобы получить DataTable и привязать DataTable к элементам управления пользовательского интерфейса. Например, для ASP.NET GridView.
DataTable dataTable =issueReportRepository.FindBy(specs);
.....
grid.DataSource=dataTable;
grid.DataBind();
В этом варианте я могу просто передать уровень домена и запросить базу данных для заданных спецификаций. И мне не нужно создавать полностью построенный сложный объект домена. Нет необходимости в объектах значений, дочерних объектах, .. Получите данные для отображения в пользовательском интерфейсе в DataTable непосредственно из базы данных и отобразите в пользовательском интерфейсе.
Но если мне нужно показать вычисляемое поле в пользовательском интерфейсе, например возвращаемое значение метода, я должен сделать это в базе данных, потому что у меня нет полностью доменного объекта. Мне нужно продублировать логику и проблемы с DataTable, такие как отсутствие intellisense и т. д.
2.) Отправьте параметры в репозиторий / DAO, чтобы получить DTO и привязать DTO к элементам управления пользовательского интерфейса.
IList<IssueDTO> issueDTOs =issueReportRepository.FindBy(specs);
....
grid.DataSource=issueDTOs;
grid.DataBind();
В этом варианте все то же, что и выше, но мне нужно создавать анемичные объекты DTO для каждой страницы поиска. Также для разных страниц поиска проблем я должен отображать разные части объектов проблемы.IssueSearchDTO, CompanyIssueTO, MyIssueDTO ....
3.) Отправьте параметры в класс Real Repository, чтобы получить полностью построенные объекты домена.
IList<Issue> issues =issueRepository.FindBy(specs);
//Bind to grid...
Мне нравится доменно-ориентированный дизайн и шаблоны. В этом варианте нет DTO или логики дублирования, но в этом варианте мне нужно создать множество дочерних объектов и объектов значений, которые не будут отображаться в пользовательском интерфейсе. Также требуется соединение многообъектов для получения полного объекта домена и стоимости производительности для дочерних игл. объекты и объекты ценности.
Я не использую какой-либо инструмент ORM. Возможно, я смогу вручную реализовать отложенную загрузку для этой версии, но это кажется немного излишним.
Какой ты предпочитаешь? Или я не так делаю? Есть ли какие-нибудь предложения или лучший способ сделать это?





У меня есть несколько предложений, но, конечно, общий ответ - «это зависит от обстоятельств».
Во-первых, вы должны использовать ORM-инструмент или у вас должна быть очень веская причина не делать этого.
Во-вторых, реализация отложенной загрузки вручную относительно проста, поэтому, если вы не собираетесь использовать инструмент ORM, вы можете просто создать свойства своих объектов, которые говорят что-то вроде:
private Foo _foo;
public Foo Foo
{
get {
if (_foo == null)
{
_foo = _repository.Get(id);
}
return _foo;
}
}
В-третьих, производительность - это то, что следует учитывать изначально, но не должно отвлекать вас от элегантного дизайна. Я бы сказал, что вы должны использовать (3) изначально и отклоняться от него только в том случае, если его производительность недостаточна. Это приводит к написанию наименьшего количества кода и наименьшему дублированию в вашем дизайне.
Если производительность снижается, вы можете легко решить эту проблему на уровне пользовательского интерфейса с помощью кэширования и / или на уровне домена с помощью отложенной загрузки. Если и то, и другое не обеспечивает приемлемой производительности, вы можете вернуться к подходу DTO, при котором вы передаете обратно только облегченную коллекцию необходимых объектов значений.
Это вопрос большой, и я тоже хотел дать свой ответ. Я думаю, что ответом технически лучший будет вариант №3. Он обеспечивает возможность наилучшего описания и организации данных, а также масштабируемость для будущих улучшений запросов отчетов / поиска.
тем не мение, хотя это может быть в целом лучшим вариантом, IMO требует огромных затрат по сравнению с другими (2) вариантами, которые являются дополнительным временем разработки для всех классов и взаимосвязей, необходимых для поддержки потребностей в отчетности (опять же при условии, что существует инструмент ORM не используется).
Я тоже борюсь с этим во многих своих приложениях, и на самом деле №2 - лучший компромисс между временем и дизайном. Теперь, если вы спрашивали о своих бизнес-объектах и обо всех их потребностях, возникает вопрос нет о том, что полностью продуманная и правильно спроектированная модель важна и ей нет замены. Однако когда дело доходит до отчетов и поиска, для меня это другое животное. №2 предоставляет строго типизированные данные в анемичных классах и не так примитивен, как жестко запрограммированные значения в наборах данных, таких как №1, и все же значительно сокращает время, необходимое для завершения проектирования, по сравнению с №3.
В идеале я хотел бы расширить свою объектную модель, чтобы охватить все потребности в отчетности, но иногда усилия, необходимые для этого, настолько велики, что создание отдельного набора классов только для нужд отчетности является более простым, но все же жизнеспособным вариантом. Несколько лет назад я задал почти такой же вопрос, и мне также сказали, что создание другого набора классов (по сути, DTO) для нужд отчетности - неплохой вариант.
Подводя итоги, можно сказать, что №3 технически лучший вариант, но №2, вероятно, является наиболее реалистичным и жизнеспособным вариантом при одновременном рассмотрении времени и качества для сложных отчетов и потребностей поиска.