简体   繁体   English

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

[英]Manage login session in desktop application: in which layer?

I have to fulfill the following requirement: 我必须满足以下要求:

[...]if the logged user is idle for more than 30 minutes, he has to be logged out. [...]如果登录的用户闲置超过30分钟,他必须退出。

where idle means "doesn't press mouse nor keyboard". 空闲意味着“不按鼠标键盘”。

Now, I was pretty sure about how to achieve this when I first read it: to me it sounded like a requirement that has to do with business logic, so I should have realized it in the business layer (having a 3-layers architecture). 现在,当我第一次阅读它时,我非常确定如何实现这一点:对我而言,它听起来像是与业务逻辑有关的要求,所以我应该在业务层实现它(具有3层架构) 。
Here some code: 这里有一些代码:

// 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();
}

This would be ideal, but there's one problem: Session should know how to detect user inactivity (and then fire logout() method)... but unfortunately this entirely depends on how the GUI is made! 这将是理想的,但有一个问题: Session应该知道如何检测用户不活动(然后触发logout()方法)......但不幸的是,这完全取决于GUI的制作方式!
[just to be clear: I know I to achieve this, but I'd like to do it independently on how I realize UI (eg Java Swing, command-line, web-based, etc)] [只是要明确:我知道我要做到这一点,但我想独立完成我如何实现UI(例如Java Swing,命令行,基于Web等)]

I mean, business layer can't (and shouldn't imo) catch user events/interaction so I should necessary realize Session in the GUI package and use it from there : in my design a layer should only interact with its strictly lower layer's interfaces and should not know anything about any higher level (Data Access Layer is indipendent (well, it depends on DB and other persistence mechanism), Business Layer only depends on Data Access Layer interfaces, Presentation Layer only depends on Business Layer interfaces). 我的意思是,业务层不能(也不应该imo)捕获用户事件/交互,所以我应该在GUI包中实现Session 从那里使用它 :在我的设计中,一个层应该只与其严格的下层接口进行交互并且不应该知道任何更高级别(数据访问层是独立的(好吧,它取决于DB和其他持久性机制),业务层仅依赖于数据访问层接口,表示层仅依赖于业务层接口)。

The problem is that just sounds wrong to me realize part of what I consider to be a business logic requirement in the presentation layer. 问题是我听起来不对,我认为在表示层中我认为是业务逻辑要求的一部分。

Btw, session expiring probably has to do too much with presentation logic since has to "listen" user inputs. 顺便说一句,会话到期可能需要对表示逻辑做太多,因为必须“监听”用户输入。

This reminds me of another pertinent question which I answered myself some time ago, but I'm going to ask this one too just to avoid any doubt: link to the question . 这让我想起了我前一段时间回答过的另一个相关问题,但我也会问这个问题,以避免任何疑问: 链接到这个问题

I'd like to hear some opinion in merit, mainly focused on good design practices. 我想听听一些有价值的意见,主要集中在良好的设计实践上。

As the requirement says 正如要求所说

if the logged user is idle for more than 30 minutes, he has to be logged out. 如果登录的用户闲置超过30分钟,他必须退出。

So here inputs are key board or mouse activity. 所以这里的输入是键盘或鼠标活动。 Of course this belongs to Presentation Layer. 当然这属于Presentation Layer。

In web application scenario, the Mouse/Keyboard activity (Utility) module trigger session time out. 在Web应用程序方案中,鼠标/键盘活动(实用程序)模块会触发会话超时。

We can use Observer/Listener pattern. 我们可以使用Observer / Listener模式。 If it is in java 如果是在java中

http://www.vogella.com/articles/DesignPatternObserver/article.html will be helpful http://www.vogella.com/articles/DesignPatternObserver/article.html会很有帮助

Using httpsession listners we can pass this activity into Business Layer. 使用httpsession列表,我们可以将此活动传递到业务层。 That means you can call Business Layer functionality to do the clean up. 这意味着您可以调用业务层功能来进行清理。

In desk top scenario, we can use Swing application where similar pattern can be used. 在桌面方案中,我们可以使用可以使用类似模式的Swing应用程序。

So the point is Presentation layer informs the other layers based on the input provided by the Utility Class. 所以关键是Presentation层根据Utility Class提供的输入通知其他层。

It can even get more exciting. 它甚至可以变得更令人兴奋。 Different timeouts on different screens (maybe screens that show a video, so the timeout is put aside while the video is on). 不同屏幕上的不同超时(可能是显示视频的屏幕,因此在视频打开时将超时放在一边)。 Different timeouts for different users (for some it should never timeout). 针对不同用户的不同超时(对于某些用户,应该永远不会超时)。 Screens that are accessible without login-in first, yet the application should "timeout" and take back to the "main" screen. 可以在不登录的情况下访问的屏幕,但应用程序应该“超时”并返回“主”屏幕。

I ended up registering the business layer application to "activity" in the presentation controls. 我最终将业务层应用程序注册到演示控件中的“活动”。 Not a beautiful site. 不是一个美丽的网站。 Would be happy to see a good solution. 很高兴看到一个很好的解决方案。

Both. 都。

Your business layer just needs to know that there has been some user activity -- it doesn't necessarily need to know what that activity is or how that activity was triggered (or even where it came from). 您的业​​务层只需要知道存在一些用户活动 - 它不一定需要知道该活动是什么或该活动是如何被触发的(甚至是它来自哪里)。

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

Whenever your presentation layer receives input of some sort (mouse movements, mouse clicks, key presses, and so on), it's up to the objects in that layer to notify the business layer that something has happened. 每当您的表示层接收某种类型的输入(鼠标移动,鼠标单击,按键等)时,由该层中的对象决定通知业务层发生了什么。

To keep things separated, you'll probably want to add some events to your Session object. 为了保持分离,您可能希望向Session对象添加一些事件。

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);
    }
    ....
}

That way when the Session object expires (or is about to expire) the session, it can loop through all of its event handlers for the respective event and invoke them. 这样,当Session对象到期(或即将到期)会话时,它可以循环遍历相应事件的所有事件处理程序并调用它们。 This will let you keep your layers separate. 这样可以让您的图层保持分离。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM