【问题标题】:How to put DAO and GUI together with MVC如何将 DAO 和 GUI 与 MVC 放在一起
【发布时间】:2015-02-12 18:26:55
【问题描述】:

我正在创建一个代表学校的 Java 应用程序。我的目标是让应用程序对新功能保持开放,因此我正在尝试对其应用一些设计模式。

到目前为止,我有一个连接到我的程序的 HSQLDB。 在数据库中可以存储

  • 学生
  • 课程
  • 考试
  • 成绩

目前的结构如下:

  • 每个对象都有包含属性 + setter 和 getter 的类
  • 对于每个对象,都有一个 DAO 来管理 DB 上的 CRUD 操作
  • 每个 DAO 都实现一个 GenericDAO 接口

如果我想创建一个新学生,我可以致电:

  • PupilDao 瞳孔 = new PupilDao();
  • pupil.connectToDB();
  • pupil.add(new Pupil(name, age,...));
  • pupil.disconnectDB();

每个 DAO 的 connectToDB() 和 disconnectDB() 方法都指向一个 DBuser-Classes 的 connect() 和 disconnect() 方法。因此,如果我想更改连接,只有一个地方可以这样做。 到目前为止,这些操作都有效。

我的问题是:

1.) 当前设计是否正确使用了 DAO?我问是因为我宁愿有一个 Dao 用于所有对象,因为现在 DAO 中有很多重复的代码。 (例如获取、更新、删除...)

现在 DB-Access 工作正常,我想使用 Swing 创建一个 GUI。尽管不是使用 MVC 模式,但我有一些这样做的经验。

2.) 据我了解,DAO + 我的对象类将是这里的模型。对吗?

3.) 我对 MVC 的理解是,在我的 View-Class(即 GUI)中,我为我的操作设置了侦听器,这些侦听器指向实现 ActionListener 接口的不同 Controller-Class,并且在我的 Controller-Classes 中,例如我将拥有一个创建新瞳孔的 actionPerformed()(使用 DAO / 模型 - 类)。我在正确的轨道上吗?

4.) 由一个大的 Controller 管理所有操作优于拥有不同的 Controller 吗?

我问这些问题是因为我阅读/观看了很多关于模式/OO-Design 的内容,并希望确保我的理解是正确的。 此外,我非常感谢您对我的设计的想法!以后可以做哪些更灵活或更好的维护?

在此先感谢您的每一个建议,并为有些冗长的解释感到抱歉!

菲利克斯

【问题讨论】:

    标签: java swing user-interface model-view-controller dao


    【解决方案1】:

    虽然我仍然不能肯定地回答我的问题,但我想我找到了合适的方法 对我来说,想分享设计(建议/答案仍然很感激!)。

    1) 应用程序入口点是主应用程序类(MVC.class)。这个类创建 使用主控制器查看。代码如下:

    public static void main(String[] args) {
    
        // view is declared as class-variable
        view = new View();
    
        MainController mcontroll = new MainController(view);
    
        view.getFrame().setVisible(true);
    }
    

    主控制器仅将视图作为参数,因为它的唯一目的是显示视图。 正如我在上面的帖子中所述,我的目标是显示来自 HSQLDB 的不同数据库表并对其进行修改。

    2) 在菜单栏中有用于管理年份、课程等的条目。如果单击一个条目,则单击类别(例如年份)的控制器将获得控制权。这里是控制器是如何改变的:

    public void addManageYearsListener(ActionListener listener) {
    
        mntmYears.addActionListener(listener);
    }
    

    上述方法位于视图类(即 GUI 类)中,但主控制器实现了 actionPerformed() 方法。为此,主控制器在其构造函数中调用视图中定义的方法,如下所示:

    public MainController(View view) {
        this.view = view;
        this.view.addManageCoursesListener(new ManageCourses());
        this.view.addManageYearsListener(new ManageYears());
    }
    

    然后将相应的类“ManageYears”定义为内部类:

    class ManageYears implements ActionListener {
    
        @Override
        public void actionPerformed(ActionEvent e) {
    
            MVC mvc = new MVC("years");
    
        }
    }
    

    这里发生的情况是,当单击菜单项时,主控制器“听到”单击(因为他正在听)并再次调用主类,尽管这次使用字符串作为参数。主类的构造函数检查字符串并设置所需的模型和控制器。见这里:

    if (controller.equals("year")) {
    
            YearDaoImpl yearDao = new YearDaoImpl();
            YearController ycontroller = new YearController(view, yearDao);
        } 
    

    “controller”是与构造函数一起传递的字符串,“yearDao”是处理与对象“year”(它本身是一个类)有关的 CRUD 操作的数据访问对象。

    所以现在可以在运行时切换控制器。

    3) 年份控制器在其构造函数中为添加和删除按钮设置 ActionListeners(就像主控制器为菜单项所做的那样),从数据库中获取数据(通过 yearDao)并将表模型设置为视图(视图有一个 setTableModel() 方法)将返回的 ResultSet 作为表模型类的参数传递:

    public void showYears() {
    
        try {
    
            con = yearDao.connectToDB();
            stmt = con.createStatement();
            rs = stmt.executeQuery("SELECT * FROM YEARS;");
    
            view.setTableModel(new YearTableModel(rs));
            con.close();
    
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
    }
    

    如您所见,yearDao 有一个 connectToDB() 方法,该方法返回一个连接(该连接实际上是从 c3p0 连接池中获取的),然后用于从数据库中获取年份的 ResulSet。然后调用 setTableModel() 方法设置 YearTableModel - 扩展 AbstractTableModel 并将 ResulSet 作为参数传递的自定义类。

    通过解释的设计,现在可以:
    1.) GUI 中只有一个表,其中填充了不同的数据库输出。
    2.)将视图与数据分开(这就是整个大惊小怪的原因;-))。
    3.) 在需要时添加新的控制器或模型,而无需更改大量代码。

    如开头所述,我仍然感谢每一个建议或改进!
    如果你能坚持到这篇文章的结尾,我希望你能找到一些可以在你自己的程序中使用的东西!

    问候, 费利克斯

    【讨论】:

      猜你喜欢
      • 2015-10-13
      • 1970-01-01
      • 2018-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-26
      • 1970-01-01
      • 2014-03-20
      相关资源
      最近更新 更多