Правильная реализация шаблона MVC в разработке GUI с использованием Swing в Java

Во-первых, я пришел из большого фона PHP с MVC, когда я начинал с PHP, я много раз просматривал, чтобы попробовать и улучшить мой MVC-подобный дизайн в PHP. Многим нравится отвечать с ответами, которые мне очень помогли.

Но после начала разработки графического интерфейса в Swing ответы о MVC в Swing совершенно другие. Например, модель также является представлением? Согласно предложениям Oracle TextElementModel здесь нет никакого логического бизнеса, все, что он делает, это разметка (установка цвета и т. д.) и настройка данных, таких как заданный текст и так далее. Когда я разрабатывал в PHP, не было такого понятия, как AbstractModel потому что мне всегда говорили, что модель - это не класс или более, это целый слой, который обрабатывает логический бизнес.

В PHP я использовал Services, Data Mappers и Domain Objects, предложенные из этого удивительного ответа, который мне очень помог в PHP: как должна быть структурирована модель в MVC?

Моя попытка

Прочитав еще раз, я решил попробовать и сделать то же самое в Java:

у меня есть ControllerContainer который создает все контроллеры:

public class ControllerContainer {

    private JFrame frame;

    public ControllerContainer(JFrame rune) {
        this.frame = frame;
    }

    public void initControllers() {
        Atest test = new Atest(frame);
        test.registerView("test", new ViewTest(test));
    }

}

Как видите, я добавляю представление с именем "test" с экземпляром ViewTest для контроллера, теперь он будет виден в кадре и может принимать входные данные.

мой Controller класс, который должен быть абстрактным, но я еще не сделал его абстрактным:

public class Controller {

    private JFrame frame;

    private Map<String, Component> views = new HashMap<String, Component>();

    public Controller(JFrame frame) {
        this.frame = frame;
    }

    protected void registerView(String title, Component c) {
        this.views.put(title, c);
        this.frame.add(c);
    }

    protected void deregisterView(String title) {
        this.frame.remove(this.views.get(title));
        this.views.remove(title);
    }

    protected Component getView(String title) {
        return this.views.get(title);
    }
}

И тестовый контроллер:

public class Atest extends Controller {

    public Atest(JFrame frame) {
        super(frame);
    }

    public void hit() {
        ((ViewTest) super.getView("test")).changeColorBlue();
    }
}

И мой TestView:

public class ViewTest extends JPanel {

    private final Atest controller;

    public ViewTest(Atest c) {
        this.controller = c;
        setBackground(Color.RED);
        setLocation(0,0);
        setSize(300, 300);
        setLayout(null);

        JButton b = new JButton("hello");
        b.setSize(150, 150);
        b.setLocation(0,0);

        b.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent arg0) {
                controller.hit();
            }
            @Override
            public void mouseEntered(MouseEvent arg0) {
            }
            @Override
            public void mouseExited(MouseEvent arg0) {
            }
            @Override
            public void mousePressed(MouseEvent arg0) {
            }
            @Override
            public void mouseReleased(MouseEvent arg0) {
            }
        });

        add(b);
    }

    public void changeColorBlue() {
        setBackground(Color.BLUE);
    }

}

Эта проблема

Как вы видите, мое представление создает новую кнопку и добавляет к ней прослушиватель мыши. слушатель будет иметь доступ к контроллеру для передачи ввода. Контроллер получает ввод и меняет представление.

По сути, контроллер мгновенно вынужден обновить представление, без каких-либо серьезных логических действий, поскольку в моем случае это не требуется.

По ссылке, которую я разместил выше, на которую ответил tereško, как я могу правильно использовать его идеи и предложения с Java Swing?

Я действительно смущен, после фона PHP.

Может я недопонимаю и все должно быть по-разному на разных языках? Но я думал, что шаблоны всегда должны быть реализованы одинаково.

Если вам нужна дополнительная информация, дайте мне знать.

2 ответа

Решение

Может быть, я неправильно понимаю, и все должно быть сделано по-разному на разных языках?

Там нет недопонимания; шаблон просто применяется по-другому.

Как отмечено в комментарии @ordous и в этом ответе @udalmik, приложение Swing может иметь несколько реализаций шаблона MVC. Как отмечалось здесь и здесь, "не каждое взаимодействие должно проходить через контроллер вашего приложения". Напротив, веб-приложение вполне может "иметь отношение 1:1 между представлениями и контроллерами".

Цитируемая здесь архитектура разделяемой модели Swing "объединяет части представления и контроллера каждого компонента в единый объект пользовательского интерфейса". Контроллеры Swing разбросаны среди потомков JComponent обычно в делегате пользовательского интерфейса компонента. В качестве конкретного примера BasicButtonUI содержит BasicButtonListener это обрабатывает взаимодействие с мышью пользователя.

Почти использовал ответ в ссылке, но тот факт, что его контроллер расширяет JPanel разрушил его, полностью смутил меня там.

Это может сбивать с толку, так как простая программа на Swing может вообще не иметь явного контроллера. Как предлагается в этом наброске, контроллер имеет прямой доступ к любому соответствующему виду и модели; он также может прослушивать взаимодействие пользователя с представлением. Этот пример был призван проиллюстрировать простейшее такое взаимодействие. Это просто совпадение, что эффект вызван взаимодействием пользователя с компонентом представления. Например, приведенное здесь моделирование имеет ControlPanel компонентов представления, которые обновляют представление и модель приложения. DisplayPanel слушает напрямую ComponentEvent это требует обновления модели. И т.п.

Тогда контроллер вашего приложения может сосредоточиться на потребностях приложения.

@ Marco13 подробно описывает это и приводит дополнительные примеры в этом ответе.

ШаблонMVC - это обычная парадигма, поэтому между языками прагматики вообще нет различий. Однако реализация и некоторые термины иногда выглядят по-разному. В Java Swing часто можно увидеть два следующих подхода:

1. Классический MVC

Контроллер - прослушивает действия пользовательского интерфейса, выполняет соответствующие обновления модели. Можно слушать действия из разных представлений.

Модель - представляет состояние и логику домена, методы для изменения состояния. Уведомляет слушателей об обновлениях модели (несколько просмотров могут прослушивать обновления). Модель независима и ничего не знает о слушателях и их логике.

Вид - отвечает за пользовательский интерфейс, расположение элементов пользовательского интерфейса, а также прослушивает обновления модели и, при необходимости, обновляет графический интерфейс. Имеет некоторые знания о модели, в примере, показанном ниже, он знает, как обрабатывать список "элементов".

Дизайн простого приложения "To Do" может выглядеть так:

введите описание изображения здесь

2. MVP (модель представления презентации)

Контроллер действует как посредник между представлением и моделью. Вид становится очень тонким и ничего не знает о модели и взаимодействует только с контроллером. Контроллер прослушивает как View, так и Model и выполняет соответствующие действия.

введите описание изображения здесь

СамSwing добавляет некоторую путаницу, потому что он использует шаблон MVC для своих компонентов пользовательского интерфейса. Каждый элемент управления UI имеет модель и представление. Это облегчает проектирование новых компонентов пользовательского интерфейса, однако, в "общей картине" всего дизайна приложения - элементы управления пользовательского интерфейса остаются на уровне просмотра.

Другие вопросы по тегам