Принцип единой ответственности и прослушиватели событий

#java #swing #events #listeners

#java #swing #Мероприятия #прослушиватели

Вопрос:

В настоящее время я пытаюсь разработать простой блокнот с графическим интерфейсом, чтобы повысить свои навыки в ООП. Я придерживаюсь принципа единой ответственности при разработке. Я разделил приложение на несколько частей, следуя принципу.

 // This class runs the whole application
public class Notepad {

   public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
                public void run() {
                new NotepadFrame();
           }
            });

    }
}
// This class is responsible for setting up a frame
public class NotepadFrame extends JFrame {

public NotepadFrame() {
        super("Notepad");

        MenuBar menuBar = new MenuBar();
        setJMenuBar(menuBar.createMenuBar());

        pack();
        setVisible(true);

    }
}
// This class sets up a menu bar
public class MenuBar {

public JMenuBar createMenuBar() {

        JMenuBar menuBar = new JMenuBar();
        Buttons buttons = new Buttons();

        menuBar.add(buttons.createFileMenuItems());
        menuBar.add(buttons.createEditMenuItems());
        menuBar.add(buttons.createFormatMenuItems());
        menuBar.add(buttons.createHelpMenuItems());

        return menuBar;
    }
}
  

Существуют также другие классы.
Кнопки — этот класс используется для создания кнопок строки меню.
MenuItemActionListeners — этот класс обрабатывает все события, запускаемые кнопками.

Правильно ли я разделил приложение в соответствии с принципом простой ответственности?

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

До сих пор я использовал один метод actionPerformed (SomeEvent e) для обработки всех событий.

 private JButton button;
private JButton button2;

public void actionPerformed(ActionEvent e) {

    Object source = e.getSource();

    if (source == button) {

    } else if (source == button2) {

    } // etc.

}
  

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

Как вы обрабатываете прослушиватели событий в своих приложениях? Как бы вы написали прослушиватели событий при разработке огромных и серьезных приложений, таких как MS Office или AutoCAD?

Ответ №1:

Смотрите Как использовать действия, в котором показано, как Action «можно использовать для отделения функциональности и состояния от компонента». Чарльз Белл HTMLDocumentEditor — это пример, который показывает, как повторно использовать существующие действия, а также создавать свои собственные на основе AbstractAction .

Ответ №2:

Вы используете одно местоположение, где обрабатываете все события, что является проблемой. В больших приложениях вы будете обрабатывать события по-разному, разные классы в вашем приложении будут обрабатывать разные события. Компоненты прослушивают только несколько событий, в которых они заинтересованы, и не все. Для exmaple a undo event имеет смысл только для paragraph object , а не для File object , a save event имело бы смысл для menu object и document object … и т.д.

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

Я бы посоветовал вам взглянуть на шаблон проектирования Observer.

Ответ №3:

Я очень рад видеть, что вы хотите использовать SRP при программировании. То, что вы сделали, вполне приемлемо. Однако всегда возникает вопрос, на каком уровне этих принципов вы хотите применить?

Кроме того, в предоставленном вами коде (метод actionPerformed) он не соответствует OCP (принципу Open Closed) и, следовательно, имеет плохой дизайн. Вместо этого у меня были бы отдельные методы для каждого типа события в каждом из тех компонентов, которые у вас есть.

Чтобы сохранить код СУХИМ, у вас может быть метод, который сообщает вам, что делать при выборе компонента. Делегируйте этому методу один из нескольких методов (из-за разного типа событий), которые вы связываете для этого компонента.

Надеюсь, это поможет..

Комментарии:

1. «Если ваше приложение выполняет несколько задач и у вас очень сложный графический интерфейс, то не рекомендуется иметь отдельные классы для каждого из компонентов» … вообще не согласен. для сложного графического интерфейса или любой другой сложной системы, если на то пошло, настоятельно рекомендуется разделить ваши классы и создавать компоненты, которые взаимодействуют друг с другом, не зная слишком много обо всей системе.

2. Рави Бхатт, я полностью согласен с тем, что вы говорите, и, следовательно, удалил свое заявление. Однако существует ограничение на степень, в которой вы хотите следовать этим принципам..