Допустим, я хочу показать форму, которая представляет 10 различных объектов в выпадающем списке. Например, я хочу, чтобы пользователь выбрал один гамбургер из 10 разных, содержащих помидоры.
Поскольку я хочу разделить пользовательский интерфейс и логику, мне придется передать форму строкового представления гамбургеров, чтобы отобразить их в выпадающем списке. В противном случае пользовательский интерфейс должен был бы копаться в полях объектов. Затем пользователь выбирает гамбургер из выпадающего списка и отправляет его обратно контроллеру. Теперь контроллеру придется снова найти указанный гамбургер, основываясь на строковом представлении, используемом формой (может быть, идентификатором?).
Разве это не невероятно неэффективно? У вас уже были объекты, из которых вы хотели выбрать один. Если вы отправили в форму целые объекты, а затем вернули определенный объект, вам не нужно будет повторно указывать его позже, поскольку форма уже вернула ссылку на этот объект.
Более того, если я ошибаюсь и вам действительно нужно отправить весь объект в форму, как я могу изолировать интерфейс от логики?
Ответы:
Прежде всего, приведенный вами пример не является невероятно неэффективным; это только немного неэффективно; его неэффективность ниже ощутимого уровня. Но, в любом случае, давайте перейдем к вопросу.
Насколько я понимаю, когда мы говорим о разделении пользовательского интерфейса и логики , мы имеем в виду избегание тесной связи .
Тесная связь относится к ситуации, в которой пользовательский интерфейс знает (и вызывает) логику, а логика знает (и вызывает) пользовательский интерфейс. Чтобы избежать тесной связи, не нужно прибегать к полной отмене связи. (Это то, к чему вы стремитесь, снося интерфейс между ними вплоть до строкового интерфейса с наименьшим общим знаменателем.) Все, что нужно сделать, это использовать слабую связь .
Слабая связь означает, что A знает B, но B не знает A. Другими словами, две вовлеченные стороны играют разные роли клиента и сервера , где клиент знает сервер, но сервер не знает клиента.
В случае пользовательского интерфейса и логики, на мой взгляд, лучший способ это организовать, рассматривая логику как сервер, а пользовательский интерфейс - как клиента. Таким образом, пользовательский интерфейс построен для логики, знает логику и вызывает логику, в то время как логика ничего не знает о пользовательском интерфейсе и просто отвечает на запросы, которые он получает. (И эти запросы приходят из пользовательского интерфейса, но логика этого не знает.)
Чтобы выразить это более практично, нигде в файлах логики исходного кода не должно быть каких-либо операторов include / import / using, которые относятся к файлам пользовательского интерфейса, в то время как файлы исходного кода пользовательского интерфейса будут полны include / import / using заявления, которые относятся к файлам логики.
Итак, возвращаясь к вашему делу, нет абсолютно ничего плохого в том, что код пользовательского интерфейса, который заполняет поле со списком, знает о классе гамбургера. Была бы проблема, если бы класс гамбургеров знал что-нибудь о комбинированных полях.
Между прочим, этот дизайн допускает еще одну вещь, которую вы должны ожидать от такой системы: должна быть возможность подключать столько логических интерфейсов, сколько вы хотите, к логике, и все это должно работать.
источник
Вы должны отделить каждую часть Модели, Представления и Контроллера, но нет никаких причин, по которым вы не можете (например) передавать объекты Модели между Контроллером и Представлением.
Так что в вашем случае
Hamburger
объекты будут частью модели. Затем вы используете свой контроллер для получения необходимого спискаHamburger
s и передаете эти объекты в представление (выпадающий список) для отображения. Когда ваш пользователь выбрал, какой гамбургер, вы можете снова передатьHamburger
объект обратно в контроллер для обработки.Дело в том, что вы все равно можете тестировать модули
Hamburger
логики «выборки » и логики «процессаHamburger
» отдельно от фактического отображения гамбургеров.источник