Существует ли набор общепринятых руководящих принципов проектирования для отделения классов Model от классов View / Controller в приложении Java Swing? Я не настолько обеспокоен тем, что View / Controller ничего не знает о модели, как наоборот: я хотел бы спроектировать свою модель так, чтобы она ничего не знала в javax.swing. В идеале у него должен быть простой API, позволяющий ему управлять чем-то столь же примитивным, как CLI. Скорее всего, это должен быть «двигатель».
Передача событий GUI в модель не так уж и сложна - исполнители действий могут вызывать API модели. Но что делать, когда модель вносит изменения в собственное состояние, которые необходимо отразить обратно в GUI? Вот для чего нужно «слушать», но даже «быть услышанным» не совсем пассивно; это требует, чтобы модель знала о добавлении слушателя.
Конкретная проблема, которая заставила меня задуматься, связана с очередью файлов. Что касается графического интерфейса пользователя, то DefaultListModel
позади него JList
есть некоторый графический интерфейс, позволяющий выбирать файлы из файловой системы и добавлять их в JList. Со стороны модели он хочет вытащить файлы из нижней части этой «очереди» (что приведет к их исчезновению из JList) и обработать их каким-либо образом. На самом деле код модели уже написан - в настоящее время он поддерживает ArrayList<File>
и предоставляет открытый add(File)
метод. Но я в растерянности относительно того, как заставить мою Модель работать с View / Controller без каких-либо серьезных, специфичных для Swing модификаций Модели.
Я очень плохо знаком с программированием на Java и GUI, до сих пор всегда занимался «пакетным» и «внутренним» программированием - поэтому я заинтересован в поддержании строгого разделения между моделью и пользовательским интерфейсом, если это возможно и если это возможно учиться.
Ответы:
Нет общепринятых (то есть де-факто ) руководящих принципов проектирования для MVC. Это не так уж сложно сделать самостоятельно, но требует некоторого планирования занятий и большого количества времени и терпения.
Причина, по которой нет определенного решения, заключается в том, что существует множество способов сделать MVC, все со своими плюсами и минусами. Так что будьте умны с этим и делайте то, что подходит вам лучше всего.
Чтобы ответить на ваш вопрос, на самом деле вы также хотите отделить контроллер от представления (чтобы вы могли использовать одну и ту же логику бизнес-правил как для приложения Swing, так и для приложения консоли). В примере Swing вы хотите отделить контроллер от
JWindow
и любого виджета в Swing. Способ, который я использовал (до использования реальных платформ), заключается в создании интерфейса для представления, которое использует контроллер:Для этого решения во время запуска необходимо зарегистрировать контроллер в представлении.
Возможно, было бы неплохо создать IoC-контейнер, чтобы выполнить все настройки за вас.
В любом случае, таким образом вы можете реализовать только консольные представления, используя те же контроллеры:
Самое интересное в том, как делать обработку событий. Я реализовал это, позволив представлению регистрироваться в контроллере с помощью интерфейса, это делается с помощью шаблона Observer (если вы используете .NET, вы бы вместо этого использовали обработчики событий). Вот пример простого «наблюдателя документа», который сигнализирует, когда документ был сохранен или загружен.
Таким образом, представление может корректно обновляться, так как оно подписывается на обновления документа. Все, что нужно сделать, это реализовать
DocumentObserver
интерфейс:Я надеюсь, что эти мотивирующие примеры помогут вам понять, как это сделать самостоятельно. Однако я настоятельно советую вам подумать об использовании фреймворков в Java, которые делают большинство вещей за вас, иначе у вас в конечном итоге будет много стандартного кода, для написания которого потребуется много времени. Существует пара многофункциональных клиентских платформ (RCP), которые вы можете использовать, которые реализуют некоторые базовые функции, которые вам, скорее всего, необходимы, такие как обработка документов в рамках всего приложения и множество базовых обработчиков событий.
Есть пара, о которых я могу думать из своей головы: Eclipse и Netbeans RCP.
Вам все еще нужно разработать контроллеры и модели для себя, но именно поэтому вы используете ORM. Примером будет Hibernate .
Контейнеры IoC - это круто, но для этого тоже есть рамки. Например, Spring (который, помимо прочего, также обрабатывает данные).
источник
Я считаю, что иногда нам нужно идти на компромисс
Как вы говорите, было бы замечательно, если бы мы могли неявно распространять уведомление об изменениях без явной инфраструктуры для наблюдаемого объекта. Для распространенных императивных языков, таких как Java, C #, C ++, их среда выполнения слишком легка, на данный момент, во всяком случае. Под этим я подразумеваю, что это не является частью спецификации языка в настоящее время.
В вашем конкретном случае, я не думаю, что это определенно плохо для определения / использования некоторого универсального интерфейса, такого как INotifyPropertyChanged (как в c #), так как он все равно не автоматически связывается с представлением - он просто говорит, что если я изменюсь, Я скажу тебе .
Опять же, я согласен, что было бы замечательно, если бы нам самим не нужно было определять уведомление об изменении, но опять же, если бы оно было неявным для всех классов, оно могло бы быть связано с накладными расходами.
источник