Что делает модель в MVC и какова связь со SwingWorker?

Я много читал о Java, Swing, MVC и SwingWorker, но я совершенно не понимаю роль модели в MVC.

Я создаю приложение с двумя кнопками:

  1. выбрать файл
  2. прочитать файл

Существует также текстовое поле, используемое для ведения журнала.

Чем я сейчас занимаюсь:

  1. Представление содержит виджеты, но не логику
  2. Методы кнопки actionPerformed() вызывают метод контроллера.
  3. Контроллер будет получать необходимые данные (включая отображение OptionPane.showOpenDialog()) для получения файла
  4. Ссылка на файл хранится в модели.
  5. Модель уведомляет (PropertyChangeSupport, шаблон Observer) представление о новом файле.
  6. Просмотр включает кнопку «Читать файл»

Мой первый вопрос: следует ли хранить состояние в модели? То есть информация, относящаяся к последовательности операций: сначала нужно выбрать файл, прежде чем его можно будет прочитать. Тогда моя Модель станет конечной машиной.

Мой второй вопрос: правильно ли я позволяю контроллеру отображать панель параметров?

Затем начинается самое интересное. Пользователь нажимает кнопку «Читать файл». Я делаю примерно то же самое, что и с кнопкой "выбрать файл". Представление вызывает контроллер, но контроллер использует SwingWorker для чтения файла, поскольку это не следует делать в EDT. SwingWorker публикует промежуточные сообщения регистрации, которые добавляются в текстовое поле через ссылку на View (метод SwingWorker.process()). Контроллер прослушивает изменения свойства «состояние» от SwingWorker. Когда «состояние» равно «ГОТОВО», контроллер вызывает функцию «get()». Если все в порядке, результаты устанавливаются в Модель. В противном случае обрабатываются исключения.

Мой третий и самый важный вопрос: разве Модель не должна читать файл?! Весь смысл MVC заключается в разделении задач со всеми преимуществами (тестируемость и т. д.). Что делать, если мне нужно новое представление (например, интерфейс командной строки)? Тогда моя модель теперь будет только моделью данных. Он понятия не имеет, как читать файл! А как насчет проблем с резьбой?

Надеюсь, вы дадите мне хороший совет. В Интернете есть множество примеров о SwingWorker, MVC и т. д. Но моя проблема не в том, как кодировать их, а в том, как проектировать.


person Rob    schedule 07.04.2011    source источник


Ответы (1)


Я думаю, что вы в значительной степени на правильном пути. Чтобы ответить на ваши вопросы один за другим:

<сильный>1. должен ли я хранить состояние в модели? да, вы можете и должны хранить состояние в своей модели — модель — это состояние и поведение, которое изменяет это состояние.

<сильный>2. правильно ли, что я позволил контроллеру показать OptionPane? да - дизайн приложения (логический поток) решает, откуда берется файл - модель, конечно, не заботится о том, как получается имя файла для чтения, просто это он получает имя файла. поток является доменом контроллера.

<сильный>3. Разве Модель не должна читать файл? Да, опять же, чтение файла является частью модели. Несмотря на то, что контроллер вызывает Swing Worker, Swing Worker концептуально является частью модели, по крайней мере, основной логикой, выполняемой Swing Worker. В идеале вся логика загрузки файла находится в классах модели. Затем контроллер может организовать вызов этого процесса с помощью рабочего процесса Swing. Контроллер решает, что загрузка файла должна происходить в фоновом потоке, и дает указание модели загрузить файл из фона. Swing worker контроллера получает события загрузки от модели и обрабатывает их, вызывая publish(), а затем process() обновляет пользовательский интерфейс.

В принципе, вы должны иметь возможность переписать все приложение как консольное без необходимости изменения модели. Естественно, вид меняется, но это потому, что теперь он должен представлять модель с использованием стандартного вывода, а не Swing. Самые большие изменения происходят в контроллере - поток приложения будет другим (выбор файла происходит из аргументов программы), контроллер больше не слушает нажатия кнопок для прямого потока, а либо имеет фиксированный поток, либо взаимодействует с пользователем через stdin. И модель потоков в контроллере другая — не нужно беспокоиться о EDT, поэтому нет необходимости в Swing Worker.

Итак, вы видите, что модель заботится о состоянии и переходит в это состояние, представление заботится о представлении состояния, а контроллер делает все остальное, в частности подключает модель к представлению.

person mdma    schedule 07.04.2011
comment
Один из лучших кратких постов, которые я видел о MVC и Swing — спасибо! - person Hovercraft Full Of Eels; 08.04.2011