Java 在这段代码中,有没有一种方法可以在不调用多个数据库调用的情况下遵守单一责任原则?

Java 在这段代码中,有没有一种方法可以在不调用多个数据库调用的情况下遵守单一责任原则?,java,design-patterns,single-responsibility-principle,Java,Design Patterns,Single Responsibility Principle,我有一部分代码基本上是通过Hibernate从数据库检索Bean对象,在将其存储回数据库之前对两个或三个属性的值进行一些更改 private void flushScoreToDatabase(String id) { int score = scoreMap.get(id); Session session = HibernateUtil.getSessionFactory().getCurrentSession(); try { session.

我有一部分代码基本上是通过Hibernate从数据库检索Bean对象,在将其存储回数据库之前对两个或三个属性的值进行一些更改

private void flushScoreToDatabase(String id) {

    int score = scoreMap.get(id);

    Session session = HibernateUtil.getSessionFactory().getCurrentSession();

    try {
        session.beginTransaction();
        Student student = (Student)session.get(Student.class, Integer.parseInt(id));
        student.setScore(score);
        session.getTransaction().commit();
        scoreMap.remove(id);
    } catch (HibernateException e) {
        session.getTransaction().rollback();
    }
}
让我们看一个真实的例子。我的应用程序的目的是允许两个人参加MCQ测试。为了防止数据库过载,每次用户提交答案时都会更新分数,我将分数计数器存储在
HashMap
中,该计数器将在测试结束时刷新到数据库中。我还需要更新一个时间戳,指示测试结束的时间

我目前的设计包括两个功能

第一个函数将分数从
HashMap
刷新到数据库

private void flushScoreToDatabase(String id) {

    int score = scoreMap.get(id);

    Session session = HibernateUtil.getSessionFactory().getCurrentSession();

    try {
        session.beginTransaction();
        Student student = (Student)session.get(Student.class, Integer.parseInt(id));
        student.setScore(score);
        session.getTransaction().commit();
        scoreMap.remove(id);
    } catch (HibernateException e) {
        session.getTransaction().rollback();
    }
}
第二个功能将涉及更新时间戳

private void updateTimestamp(String id) {
    Session session = Hibernate.getSessionFactory().getCurrentSession();

    try {
        sesssion.beginTransaction();
        Student student = (Student)session.get(Student.class, Integer.parseInt(id));
        student.setEndTime(timestamp);
        session.getTransaction().commit();
    } catch (HibernateException e) {
        session.getTransaction().rollback();
    }
}
这两个函数都将由另一个函数包装,该函数从经过身份验证的会话中获取用户的
id

这是相当昂贵的,因为这涉及到两个
SELECT
语句以及两个
UPDATE
语句,只是为了更新同一用户的两个不同属性


在SRP?

< P>中有没有一种更简洁的方法来设计代码?通常SRP是参照一个类或模块来讨论的,但是我认为正确的考虑函数的含义是正确的,一个“RabP袋”函数的工作是“X和Y和Z”可能不是好的设计。 另外,执行两个单独的事务来更新分数和时间戳肯定是过度的

我倾向于从商业意义上考虑这些功能,比如说:

snapshotTest()

并且有一个实用功能,可以更新两个学生使用的学生分数


顺便说一句,所有这些事务性的东西都在妨碍您的业务逻辑,您不能使用EJB或Spring将其推送到容器中吗?

它与SRP有什么关系?你需要重新思考你的问题是什么。我认为你对单一责任原则有一个过于微观的概念。“此类负责将内存状态与数据库同步”是定义职责的一个非常好的级别。“一个方法一次只允许更新一个字段”太愚蠢了。@aff那么您认为两个更新都在同一个函数中完成是可以的吗?如果不是两个简单的更新,而是对不同字段的四到五个更新,每个更新都需要多行代码来推导更新值,会怎么样?我过去经常这样做,当我回去阅读代码时,它看起来相当混乱。是否考虑使用IOC容器和声明性事务管理?这将使hibernate会话很容易跨越多个方法调用。(同样,现实,“良好的OO设计”和与关系数据库的高性能交互是天敌。)感谢你的回答,我同意有两个单独的事务来更新分数和时间戳是过分的。我想我应该根据你的建议重新考虑一下设计。我也同意事务性的东西相当混乱。这是我的第一个Java应用程序,所以我在第一次启动时还没有发现Spring之类的东西。我希望在同一个应用程序中保持一致,所以我现在仍然坚持这种方式。如果我从一个新的Java应用开始,我肯定会使用Spring或类似的工具。再加上djna所说的,这个问题中的设计看起来是以数据为中心的,而不是以逻辑为中心的。我的经验是,面向对象的设计非常适合以逻辑为中心的应用程序,但不适合面向数据的应用程序。原因是以数据为中心的应用程序需要更结构化的方法(例如,事务脚本模式)。