У нас есть многоуровневое приложение или, по крайней мере, оно находится в процессе перехода к одному, разбитое на следующие группы:
Чтобы сделать остальную часть этого вопроса более конкретной, я опишу конкретный случай.
У нас есть пользовательский интерфейс, за которым стоит объект контроллера (уровень бизнес-логики). Этот контроллер общается с базой данных через другой объект (уровень доступа к данным).
В данном контексте пользовательский интерфейс позволяет пользователю выбрать сотрудника, с которым будет связана выполняемая операция. Поскольку существуют правила относительно того, каких сотрудников может выбирать пользователь (ну, на самом деле, любой мир за пределами контроллера), контроллер предоставляет для этого две вещи:
Пользовательский интерфейс может читать список и использовать его для заполнения поля со списком.
В версии 1 этого приложения поле со списком содержит идентификационный номер сотрудника + имя сотрудника.
Все хорошо...
... до версии 1.1 исправлена ошибка. Пользователь жалуется, что не может выбрать между Джимми Олсон и Джимми Олсон, потому что приложение не позволяет ему достаточно легко узнать, что есть что. Он знает, что один Джимми работает в отделе продаж, а другой - в отделе разработки, поэтому исправление для этой версии 1.1 - просто добавить косую черту + название отдела в поле со списком. В версии 2 мы бы предпочли заменить поле со списком на поле со списком с поддержкой столбцов, удалив косую черту, но в версии 1.1 это то, что выбрано, чтобы минимизировать риск дальнейших ошибок.
Другими словами, поле со списком будет содержать:
Однако код пользовательского интерфейса не имеет кода SQL или какого-либо способа получить доступ к этому отделу, и поэтому мы должны перейти к контроллеру и посмотреть на код там. Контролеру не нужен отдел, и, честно говоря, ему даже не нужно имя сотрудника, идентификационного номера достаточно, поэтому в контроллере нет ничего, что запрашивало бы или что-то делало с отделом. Итак, мы должны спуститься на уровень доступа к данным и изменить там SQL.
Этот раствор откровенно пахнет.
Если у этого контроллера есть несколько интерфейсов с разными требованиями, у нас есть три возможных решения:
Ни одно из вышеперечисленных решений не вызывает оптимизма.
Что мне интересно, мы полностью сбились с курса? Как бы ты это сделал? Есть ли четвертое и пятое решение ниже трех вышеупомянутых?
На этот вопрос: Разделение проблем, принятый ответ содержит эту цитату:
The separation of concerns is keeping the code for each of these concerns separate. Changing the interface should not require changing the business logic code, and vice versa.
Означает ли это, что весь уровень контроллера / доступа к данным должен предоставить нам все, что ему нужно для выполнения своей работы (например, идентификационные числа сотрудников), а затем пользовательский интерфейс должен обратиться к базе данных и запросить дополнительную информацию про эти конкретные сотрудники?





На мой взгляд, у вас есть две возможности:
У обоих есть компромиссы. Первый предоставляет гораздо больше информации, возможно, потребителям, которые не имеют права на эту информацию. Второй передает намного меньше информации за транзакцию, но требует больше транзакций. Первый не требует изменения API каждый раз, когда у вас появляется дополнительная информация, но меняет XML. Второй сохраняет интерфейс существующих API-интерфейсов таким же, но предоставляет новые API-интерфейсы по мере необходимости. И так далее.
@lassevk - Как я уже сказал, это компромисс. Вы должны решить, какие компромиссы лучше всего подходят для вас.
Ладно, мне все это не нравится. Например, если мы отправим только то, что нужно контроллеру, нам понадобится, как вы говорите, способ сказать «Ну, мне нужно больше», и это должно быть как можно более экономичным, а не выполнять один sql на сотрудника ...