Это правильный дизайн MVC? Советы по MVC дизайн связи в потоке

1

В последний день я прочитал много-много учебников и блогов о шаблоне MVC. Теперь я в значительной степени понимаю концепцию, но мне показалось, что в каждом учебнике была еще одна концепция для реализации этого шаблона в Java. Поэтому я решил написать свое собственное приложение, а затем попросить совета у более высококвалифицированных программистов. (Изучение - это что-то вроде моей вещи).

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

MainClass:

public class MainClass {enter code here
    public static void main(String[] args){

        MainController controller = new MainController();
        controller.initView();
    }
}

Класс контроллера:

public class MainController implements ActionListener{

private ExtractorStatics stat;
private MainView mainview;
private BusinessExtractor bExtractor;
private InfoboxTextPane infobox;
private BufferedImage logoGS;

public MainController(){
     stat = new Statics(); 
     model = new Model();
     mainview   = new MainView();
}
public void initView(){
    if(mainview!=null){
        mainview.setActionListener(this);
        mainview.setItemListener(new ComboBoxItemListener(this));
        mainview.setVisible(true);
    }
}

@Override
public void actionPerformed(ActionEvent event) {
    String command = event.getActionCommand();
    if(command.equalsIgnoreCase(stat.SCAN_ACTION_COMMAND)){
        this.quickScanButtonAction();
    }
}


private void quickScanButtonAction(){
    infobox = mainview.getInfobox();
    ProcessingInformation information = model.quickScan();
    InputStream informationStream = information.getInformationStream();
    BufferedReader infoReader = new BufferedReader(
                new InputStreamReader(informationStream));
    String line;
    try {
    while ((line = infoReader.readLine()) != null) {
                infobox.appendLine(line);
            }

            infoReader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("End reached");
    }
    else
        infobox.appendLine("Bitte Eingabe überprüfen.");
}
public void comboBoxChanged() {
    //do some fancy stuff
}
   }

 class ComboBoxItemListener implements ItemListener{
        MainController mc;
    public ComboBoxItemListener(MainController mc){
        this.mc=mc;
    }
    @Override
    public void itemStateChanged(ItemEvent e) {
        mc.comboBoxChanged();
    }   
}

MainView Class:

    public class MainView extends JFrame {


    private static final long serialVersionUID = 559229524422932258L;
    private JPanel contentPane;
    private JTextField txt_stichwort,txt_loc;
    private JButton btn_quickscan;
    private JTable table;
    private JLabel label;
    public  InfoboxTextPane txtpn_infobox;
    private String lineSep;
    private final JComboBox<String> combobox;
    /**
     * Create the frame.
     */
    public MainView() {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | InstantiationException
                | IllegalAccessException | UnsupportedLookAndFeelException e3) {
            // TODO Auto-generated catch block
            e3.printStackTrace();
        }

        lineSep=System.lineSeparator();
        Statics stats=new Statics();



        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 800, 620);
        contentPane = new JPanel();
        contentPane.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
        setContentPane(contentPane);
        contentPane.setLayout(null);


        txt_subject= new JTextField();
        txt_stichwort.setBounds(88, 47, 318, 20);
        pan_suche.add(txt_stichwort);
        txt_stichwort.setColumns(10);

        combobox = new JComboBox<String>();
        combobox.setBounds(88, 16, 318, 20);
        pan_suche.add(combobox);
        combobox.setModel(new DefaultComboBoxModel(new String[] {"Item1", "Item2"}));

        txt_loc = new JTextField();
        txt_loc.setBounds(88, 79, 318, 20);
        pan_suche.add(txt_loc);
        txt_loc.setColumns(10);



        btn_quickscan = new JButton("Quick Scan");
        btn_quickscan.setActionCommand(stats.SCAN_ACTION_COMMAND);
        btn_quickscan.setBounds(10, 23, 130, 30);
        pan_dos.add(btn_quickscan);

        //a few more buttons that have other action commands defined by statics
        //more labels and other GUI components


    }
    public InfoboxTextPane getInfobox(){
        return this.txtpn_infobox;
    }
    public String getSearchSubject(){
        return this.txt_stichwort.getText();
    }

    public String getSearchLocation(){
        return this.txt_loc.getText();
    }
    public String getSearchWebsite(){
        return (String)this.combobox.getSelectedItem();
    }
    public JComboBox<String> getComboBox(){
        return this.combobox;
    }
    public JLabel getLogoLabel(){
        return this.label;
    }

    public void setActionListener(ActionListener al){
        try {

            btn_quickscan.addActionListener(al);
        } catch (NullPointerException e) {
            e.printStackTrace();
        }
    }

    public void setItemListener(ItemListener il){
        this.combobox.addItemListener(il);
    }
    }

Модельный класс:

public class Model {
private ExecutorService exeService;

public Model(){
    exeService =Executors.newCachedThreadPool();
}

public ProcessingInformation quickScan(){ 
    QuickScanRoutine qs = new QuickScanRoutine();
    Future<String> result = exeService.submit(qs);
    return qs.getProcessingInformation(); 
}

}

Стандартный класс (по вызову):

public class QuickScanRoutine implements Callable<String> {
    private ProcessingInformation pi;
    private BufferedWriter writer;



public QuickScanRoutine(){
    pi = new ProcessingInformation();
    PipedOutputStream pos = new PipedOutputStream();
    PipedInputStream pis;
    writer = new BufferedWriter(new OutputStreamWriter(pos));

    try {
        pis = new PipedInputStream(pos);
        pi.setInformationStream(pis);
    } catch (IOException e) {
        e.printStackTrace();
    }

}

public ProcessingInformation getProcessingInformation(){
    return this.pi;
}

@Override
public String call() throws Exception {

    //ofcourse this isnt the real purpose of this Class but I want to     'demonstrate writing to the stream'

    for(int i =0; i<100;i++){
        writer.write("Hello");
        writer.newLine();
        writer.flush();
    }
    writer.close();
    return "Routine has been executed sucessfully!";
}

}

Обработка информации:

public class ProcessingInformation {
PipedInputStream informationStream,resultDataStream;

    public void setInformationStream(PipedInputStream info) {
        this.informationStream = info;
    }
    public void setResultDataStream(PipedInputStream data){ 
//I will need this stream for further tasks
        this.resultDataStream = data;
    }

    public InputStream getInformationStream(){
    if(informationStream!=null){
        return informationStream;
    }
    else
        return null;
}

public InputStream getResultDataStream(){
    if(informationStream!=null){
        return informationStream;
    }
    else
        return null;
}
}

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

  • Это правильный дизайн MVC?
  • Является ли это подходящим способом для знакомства с этой модельной нитью? (PipedStream)

Это будут мои основные вопросы, но я благодарен и открыт всем вашим советам.

  • 0
    Взгляните на мою статью Java Swing File Browser . Я проиллюстрировал один из способов кодирования Swing-приложения с использованием шаблона MVC.
  • 0
    Спасибо за эту ссылку, я ценю это.
Теги:
multithreading
model-view-controller
design-patterns

3 ответа

1
Лучший ответ

Я согласен с ответом Абхи Беккерта на некоторые аспекты - как правило, следующее:

  1. Для модели никогда не приемлемо общаться ни с чем другим, кроме модели.
  2. Представление должно сообщаться только с другими объектами представления и не иметь сведений о контроллере.

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

Когда вы открываете документ Word в текстовом процессоре, таком как MS-Word, страница может иметь различные макеты, такие как "Портрет", "Пейзаж", "Печать" и "Html". В каждом из этих макетов видимые пользовательские элементы различны. Однако данные одинаковы. Следовательно, наиболее логичным способом решения этой проблемы было бы либо:

  • Попросите диспетчера отправить команду модели для обновления соответствующего вида.
  • Попросите контроллер запросить модель для получения данных и просто передать полученные данные в представление для рендеринга.

Я прошел через код, который вы публикуемые и определили, что ваш контроллер знает о содержании представления для например, MainController называет в MainView.getinfobox().Based на объяснении выше, вы хотели бы изменить.

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

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

  • 0
    В приложении MVC представление может считывать данные непосредственно из модели. Да, представление должно иметь экземпляр модели, но модель по-прежнему отделена от представления.
  • 0
    @GilbertLeBlanc Я согласен, но я хочу сказать, что контроллер должен знать что-либо о композиции View.
Показать ещё 2 комментария
1

Я не программист на Java, но я хорошо знаю MVC:

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

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

То же самое касается представления - он должен только взаимодействовать с другими объектами представления.

Все коды связи поступают в контроллер позже. Модель и представление должны иметь произвольные обратные вызовы и т.д., Которые настраиваются и используются объектами в уровне контроллера.

Точка MVC должна сделать вашу модель и просматривать полностью независимо от остальной части вашего кода. Они должны иметь нулевые внешние зависимости.

  • 0
    Но модель просто общается методом геттера. Таким образом, контроллер получает это. А затем другой класс модели пишет в поток. Это также не рекомендуется? Хотя вся суть MVC в том, что вы можете использовать модель самостоятельно. Как вызов метода quickscan () из любого другого интерфейса пользователя или из консоли? Или я ошибся?
  • 0
    @ user3187049 Правильно, в вашем коде модель не подключена. Однако у вас есть «модель» кода внутри вашего контроллера и просмотра кода. Весь этот код необходимо переместить в класс модели (или классы), и вам нужно переместить его таким образом, чтобы он не знал о контроллере или представлении.
Показать ещё 2 комментария
0

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

Представление содержит все графические элементы и имеет экземпляр контроллера, поскольку представление должно реализовать контроллер в качестве слушателя для действий, выполняемых в форме. (Buttonclicks и т.д.). Но представление не должно содержать никакой логики, насколько это возможно.

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

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

  • Мое понимание о праве?

Я несколько других вопросов, что я ссылаюсь на шаблон MVC:

  • В учебном пособии я увидел реализацию шаблона MVC, где представление было Observer, а модель была Observable (Observer Pattern). Это кажется логичным для меня, поскольку модель перепечатывает данные, которые должны отображаться в представлении. И мнение должно реагировать на изменения данных модели. Но является ли это подходящим способом реализации реальности между моделью и точкой зрения?
  • Возможно ли иметь несколько классов моделей для одной формы? Например, одна модель для таблицы, а другая для текстовой панели?
  • Является ли это подходящим способом или даже наилучшим способом реализовать все интерфейсы, которые необходимы для кнопок и т.д. В контроллере, и установить их так, чтобы кнопки в режиме просмотра были настроены?
  • Прахлад, ты сказал:

Я просмотрел код, который вы опубликовали, и определил, что ваш контроллер знает о содержимом представления, например, вызовы MainController в MainView.getinfobox(). Исходя из приведенного выше объяснения, вы хотели бы его изменить.

Означает ли это, что контроллер не должен манипулировать формой вообще? Теперь я думаю, что представление просто манипулирует собой данными, которые предоставляет модель, потому что представление "наблюдает" данные модели и чем само изменение. Это верно?

  • 0
    Переполнение стека является сайт вопросов и ответов. Никто здесь не может обучить вас в изучении MVC. Есть и другие веб-сайты, где вы можете нанять репетитора, который поможет вам изучить MVC.
  • 0
    Хорошо, извините, но я действительно не ожидаю, что кто-нибудь будет обучать меня, но я прочитал много учебников и текстов по этой теме, и теперь у меня все еще есть некоторые вопросы. Вот почему я задал конкретные вопросы, и большинство из них даже да, без вопросов. Поэтому я просто прошу кого-нибудь ответить на этот вопрос. Потому что чтение блогов и учебников мне очень помогло, но это те вопросы, которые остались мне.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню