ОБНОВЛЕННЫЙ:
У меня есть настольное приложение со следующим взаимодействием компонентов:
Если контроллер просит, чтобы сервис сделал что-то, но для того сервиса нужно что-то больше от контроллера сначала (т.е. данные, которые контроллер должен использовать UI для получения от пользователя), как сервис должен заставить контроллер делать так?
Я удобен с понятием это
и так далее.
Однако относительно Контроллера, общающегося с Сервисом, какой метод является лучшим для этого? Если:
Мне нравится первая опция, потому что второе могло означать взрыв класса, где Вам нужен a ServiceResult
- класс стиля для каждого Сервисного метода.
Я спрашиваю из-за курса, который Сервисный компонент не может сказать UI, что сделать, только контроллер может, но контроллер не знает, что сказать UI, не получая некоторую обратную связь от Сервиса.
Что Вы думаете?
Ваш лучший вариант, вероятно, для использования моделей события или делегата - например, контроллер подписывается на событие «нужна дополнительная информация» и отображает соответствующую форму. Возвращая дополнительные данные к сервису можно сделать несколько разных способов, но в значительной степени зависеть от специфики вашего дизайна (например, ваши услуги без природных и т. Д.)
У вас были написаны тесты на подразделение для вашего обслуживания? Если нет, этот процесс, вероятно, поможет вам уточнить, что вы хотите из вашего дизайна.
Первое, что вам нужно иметь в виду, при разработке сервисного слоя / классов - сделать их очень многоразовым. Они должны быть объекты атомной службы, которые могут служить не только вашим контроллером, но и любым другим клиентам в будущем.
Здесь есть несколько вопросов:
Как контроллер находит службу?
Если вы хотите иметь очень многоразовые, расширимые и ... объекты сервиса, зависимость между вашим контроллером и классами обслуживания должна быть слабо связана. Избегайте любых тесных методов муфты. Вместо этого пытайтесь inject класс обслуживания к вашему контроллеру (с помощью контейнера IOC), а также вы можете использовать Услуги дизайна дизайна локатора .
Как общаться с сервисом?
Ну, это зависит от размера вашего приложения. Вы можете перейти на корпоративные технологии, такие как веб-сервисы, просто используйте услуги приложений. На основании этого вы определяете протокол между контроллером и службой.
Какие данные должны возвращаться услугу к контроллеру?
Помните, что сервисный слой не должен ничего знать о навигации пользовательского интерфейса. Это ответственность контроллера, чтобы решить, куда идти и что делать на основе ответа объекта сервиса. Почему? Представьте себе, что этот класс услуг должен использоваться для другого пользовательского интерфейса (скажем, из веб-сайта, чтобы Flex, Silverlight или Desktop). Если вы добавляете логику навигации (в качестве экстремального примера, логика / форматирования / пользовательской интерфейсы) в классе обслуживания, он не будет многоразовым для другой системы пользовательского интерфейса, а также она не будет многонаправлена для даже других классов и контроллеров услуг в том же приложении. Отказ
Нижняя строка, попытайтесь сохранить класс услуг чистоте любой логики навигации. Контроллер действительно предназначен для этой цели.
Увидеть мой вопрос здесь
Есть некоторые недостающие данные, чтобы лучше ответить вам вопрос:
Это веб или рабочий стол?
Если на рабочем столе - это отключенный сценарий? (E.g. Богатый клиент с удаленными службами) или клиент и обслуживание на одной машине?
Если в Интернете - это классическое приложение Web 1.0? (Просмотр создан как страница) или богатый клиент? (Ajax, Flex, Silverlight), где контроллер иногда может быть в клиенте? (Flex)
Все это может значительно повлиять на решения.
Кстати, вы опускали модель в целях?
Я много работаю с MVC (хотя мой аромат java веб-приложения), и я часто наткнулся на некоторые ситуации, где кажется, что услуга должна как-то взаимодействовать с контроллером. Но в каждом случае оказалось, что я делаю что-то не так в контроллере или интерфейс моего сервиса, не достаточно гибкий (I.E., мелкозернистый).
Когда служба не получает достаточно данных, это связано с пользователем, предоставляющим неверный ввод? Если это так, то контроллер должен выполнять проверку на входе и отобразить соответствующую подсказку или сообщение об ошибке.
Если ожидается, что пользователь не будет предоставлять все данные одновременно, то контроллер должен знать, что служба не примет данные, как есть. Следовательно, контроллер должен управлять разговором с пользователем через пользовательский интерфейс, затем, наконец, пройти все на сервис в конце.
Или, возможно, контроллер должен запрашивать сервис на протяжении всего потока мастера. В этом случае интерфейс службы, вероятно, должен быть более мелким зерном.
Я бы пошел с вариантом # 1, который вы предложили. Если контроллер способен сбрать все необходимые входы из пользовательского интерфейса и предоставление им услуге, но это не выполняет этого, то служба должна выбрасывать исключение. Использование исключения разумно, потому что вы пытаетесь пройти неверные данные на сервис. (Это не изменяет тот факт, что исключения не должны быть брошены для управления потоком программы, а скорее указывают на то, что контроллер фактически прикручен в предоставлении службы некоторые недопустимые данные.)
Рассматривали ли вы возможность использования Model View Presenter?
Ваши представления пользовательского интерфейса будут реализовывать интерфейсы, и эти интерфейсы будут известны вашим службам. Таким образом, ваши службы могут обратиться к UI за дополнительной информацией для выполнения своих задач. Это своего рода инверсия зависимости (pdf).