有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

桌面应用程序中的java管理登录会话:在哪一层?

我必须满足以下要求:

[...]if the logged user is idle for more than 30 minutes, he has to be logged out.

其中,空闲表示“不按鼠标或键盘”

现在,当我第一次读到它时,我非常确定如何实现这一点:对我来说,它听起来像是一个与业务逻辑有关的需求,因此我应该在业务层(具有3层体系结构)中实现它
下面是一些代码:

// simplified and generalized version of my login method
public boolean login(String email, String password) {
    user = dao.read(email, password); //returns either null or the user
    boolean logged = user != null;
    if (logged) {
       // initialize Session somehow, let's say for example:
        Session.start();
    }
    return logged;
}

// simplified and generalized version of my logout method
public void logout() {
    operatore = null;
    // terminate Session somehow, let's say for example:
    Session.destroy();
}

这将是理想的,但有一个问题:Session应该知道如何检测用户的不活动(然后触发logout()方法)。。。但不幸的是,这完全取决于GUI的制作方式
[需要明确的是:我知道我很想实现这一点,但我想独立完成这一点,具体取决于我如何实现UI(例如Java Swing、命令行、基于web的等)]

我是说,业务层不能(也不应该)捕获用户事件/交互,因此我应该在GUI包中实现Session,并且从那里使用它:在我的设计中,一个层应该只与其严格较低层的接口交互,而不应该知道任何更高级别的信息(数据访问层是独立的(它依赖于数据库和其他持久性机制),业务层只依赖于数据访问层接口,表示层只依赖于业务层接口)

问题是,在我看来,听起来很不对,在实现层中实现了我认为是业务逻辑需求的一部分。

顺便说一句,会话过期可能与表示逻辑有太多关系,因为它必须“侦听”用户输入

这让我想起了另一个相关的问题,我不久前回答了自己,但我也要问这个问题,以避免任何疑问:link to the question

我想听取一些关于优点的意见,主要集中在良好的设计实践上


共 (3) 个答案

  1. # 1 楼答案

    两者都有

    您的业务层只需要知道有一些用户活动,它不一定需要知道该活动是什么,或者该活动是如何触发的(甚至不需要知道它来自何处)

    public class Session {
        ...
        public static void keepAlive() {
            // update last activity fields with new timestamp
        }
        ....
    }
    

    每当您的表示层接收到某种类型的输入(鼠标移动、鼠标单击、按键等),就由该层中的对象通知业务层发生了什么

    为了使事情保持分离,您可能需要向会话对象添加一些事件

    public interface SessionExpiringEventHandler {
        void sessionExpiring();
    }
    
    public interface SessionExpiredEventHandler {
        void sessionExpired();
    }
    
    public class Session {
        ...
        private List<SessionExpiringEventHandler> expiringHandlers;
        private List<SessionExpiredEventHandler> expiredHandlers;
        ...
        public static void addExpiringEventHandler(SessionExpiringEventHandler h) {
            expiringHandlers.add(h);
        }
        public static void addExpiredEventHandler(SessionExpiredEventHandler h) {
            expiredHandlers.add(h);
        }
        ....
    }
    

    这样,当会话对象在会话到期(或即将到期)时,它就可以为相应的事件遍历其所有事件处理程序并调用它们。这将使你保持你的层分开

  2. # 2 楼答案

    正如要求所说

    if the logged user is idle for more than 30 minutes, he has to be logged out.

    所以这里的输入是键盘或鼠标活动。当然,这属于表示层

    在web应用程序场景中,鼠标/键盘活动(实用程序)模块触发会话超时

    我们可以使用观察者/监听器模式。如果是java的话

    http://www.vogella.com/articles/DesignPatternObserver/article.html会有帮助的

    使用httpsessionlistners,我们可以将此活动传递到业务层。这意味着您可以调用业务层功能来进行清理

    在桌面场景中,我们可以使用类似模式的Swing应用程序

    所以重点是表示层根据实用程序类提供的输入通知其他层

  3. # 3 楼答案

    它甚至可以变得更令人兴奋。不同屏幕上的不同超时(可能是显示视频的屏幕,因此在视频打开时将超时放在一边)。不同用户的不同超时(对于某些用户,它永远不会超时)。无需先登录即可访问的屏幕,但应用程序应“超时”并返回“主”屏幕

    最后,我将业务层应用程序注册到演示控件中的“活动”。不是一个美丽的地方。我很高兴看到一个好的解决方案