Java Swing MVC - 实现模型的最佳实践

标签 java swing model-view-controller model

我正在尝试找出创建/使用 MVC 模式模型的最佳方法。 我有一个 Person 列表(数据库)和一个 View,它表示某些 Person 的部分数据。

问题是: 如果我有一个大型数据库,其中包含每个人的大量数据,并且我有一个仅显示一个人的少量数据的 View 面板,我应该创建一个仅维护该 View 的可表示数据的模型,还是应该使用 数据库直接作为模型?

我将有不同的 View ,它们代表同一数据库的不同数据。数据库应该是所有 View 的模型还是我需要为每个 View 面板创建小型模型?

这是一个小示例,其中包含 1 个 View 面板和数据库,直接作为所有 View 面板的模型:

Main.java

import java.awt.EventQueue;
import javax.swing.JFrame;

public class Main {
    private JFrame frame;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    new Main();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public Main() {
        initialize();
    }

    private void initialize() {

        Database.getInstance();                         // model ?
        View view = new View();                         // view
        Controller controller = new Controller();       // controller

        Database.getInstance().addObserver(view);
        view.addController(controller);

        frame = new JFrame();
        frame.add(view.createView());
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }
}

Person.java

public class Person {

    private String name;
    private int age;
    private String sex;

    public Person(String name, int age, String sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public String getSex() {
        return sex;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

}

Database.java(模型)

import java.util.ArrayList;
import java.util.List;
import java.util.Observable;

public class Database extends Observable {

    private static Database instance = null;
    private List<Person> database = new ArrayList<Person>();

    private Database() {
        this.database = createDataBase();
    }

    public static Database getInstance() {
        if (instance != null)
            return instance;
        else
            return instance = new Database();
    }

    private List<Person> createDataBase() {
        List<Person> database = new ArrayList<Person>();
        database.add(new Person("A", 25, "male"));

        return database;
    }

    public List<Person> getDatabase() {
        return database;
    }

    public void changeData(String name, int age, String sex) {
        database.get(0).setName(name);
        database.get(0).setAge(age);
        database.get(0).setSex(sex);
        setChanged();
        notifyObservers();
    }

}

View.java

import java.awt.BorderLayout;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class View implements Observer {

    private JLabel nameLabel;
    private JLabel ageLabel;
    private JButton changeDataButton;

    public View() {
        this.nameLabel = new JLabel();
        this.ageLabel = new JLabel();
        this.changeDataButton = new JButton("Change Data");
    }

    public JPanel createView() {
        JPanel viewPanel = new JPanel(new BorderLayout());
        viewPanel.add(new JLabel("View only name and age"), BorderLayout.NORTH);
        viewPanel.add(nameLabel, BorderLayout.WEST);
        viewPanel.add(ageLabel, BorderLayout.EAST);
        viewPanel.add(changeDataButton, BorderLayout.SOUTH);

        inizializeView();

        return viewPanel;
    }

    private void inizializeView() {
        this.nameLabel.setText(Database.getInstance().getDatabase().get(0).getName());
        this.ageLabel.setText("" + Database.getInstance().getDatabase().get(0).getAge());
    }

    public void addController(Controller controller) {
        changeDataButton.addActionListener(controller);
    }

    @Override
    public void update(Observable obs, Object obj) {
        nameLabel.setText(((Database) obs).getDatabase().get(0).getName());
        ageLabel.setText("" + ((Database) obs).getDatabase().get(0).getAge());
    }

}

Controller.java

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Controller implements ActionListener {

    public Controller() {

    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
        Database.getInstance().changeData("B", 30, "female");       // change model
    }

}

如您所见,view 面板仅代表 Person 的 2/3 字段。我应该为此 View 面板实现一个单独的模型,仅代表 PersonString nameintage 还是我应该保留所有内容?

最佳答案

As You can see, view panel represents only 2/3 fields of Person. Should I implement a separate model for this view panel which represents only String name and int age of Person or I should leave everything as it?

我建议您保持模型不变。这是 M-V-C 的好处之一,一个模型可以以多种不同的方式显示,这可能意味着仅显示模型状态的一部分,就像您使用完全不同的 GUI 库或平台进行或显示它一样(例如,Android)。此外,甚至更重要的是,通过这种方式,对单个模型的更改会反射(reflect)在共享相同模型的所有 View 中

关于Java Swing MVC - 实现模型的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46253722/

相关文章:

java - 如何在具有单独索引的 Java 8 中应用 reduce/collect 过滤器?

java - 如何链接 JSP、servlet 和 Java View bean?

java - 通过选中另一列中的一项来启用和禁用 JTable 复选框

javascript - Angular JS 入门 - 结构和其他问题

java - 如何提取嵌套 JSON 数据中的数组值

java - 从单例切换到应用程序对象,仍然出现空指针异常

Java swing与prepareRenderer的问题

java - 如何从 java 中的 Action Listener 获取按钮 (JButton) 的类或类型?

javascript - 主干 - 为什么 collection.reset 不触发模型事件?

model-view-controller - 语言翻译在 MVC 模式中的位置在哪里?