如何将DAO和GUI与MVC结合在一起

时间:2014-12-14 15:30:41

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

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

到目前为止我所拥有的是连接到我程序的HSQLDB。 在数据库中可以存储

  • 学生
  • 课程
  • 考试
  • 等级

目前的结构如下:

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

如果我想创建一个新学生我可以打电话:

  • PupilDao pupil = new PupilDao();
  • pupil.connectToDB();
  • pupil.add(新学生(姓名,年龄,......));
  • 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-Classes,在我的Controller-Classes中,我将例如一个actionPerformed()创建一个新的Pupil(使用DAO / Model - Classes)。我在这里走在正确的轨道上吗?

4。)让一个大型控制器管理所有不同控制器的操作是否有利?

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

提前感谢您的每一个建议,并对这个有点长的解释感到抱歉!

菲利克斯

1 个答案:

答案 0 :(得分:0)

虽然我仍然无法回答我的问题,但我认为我找到了合适的方法 对我而言并希望分享设计(建议/答案仍然受到赞赏!)。

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() - 方法。为此,main-controller在其构造函数中调用视图中定义的方法,如:

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");

    }
}

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

if (controller.equals("year")) {

        YearDaoImpl yearDao = new YearDaoImpl();
        YearController ycontroller = new YearController(view, yearDao);
    } 

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

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

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

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.)在需要时添加新的控制器或模型,而无需更改大量代码。

正如一开始所提到的,我仍然感谢每一个建议或改进!
如果你做到这篇文章的结尾,我希望你在自己的程序中找到了一些东西!

问候, 菲利克斯