5

次の要件を満たす必要があります。

[...]ログに記録されたユーザーが30分以上アイドル状態の場合は、ログアウトする必要があります。

ここで、アイドルとは「マウスもキーボードも押さない」ことを意味します。

さて、最初に読んだとき、これをどのように達成するかについてはかなり確信していました。私には、ビジネスロジックに関係する要件のように聞こえたので、ビジネスレイヤー(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();
}

これは理想的ですが、1つの問題があります。Sessionユーザーの非アクティブを検出する方法(そしてメソッドを起動するlogout()方法)を知っている必要があります...しかし、残念ながら、これはGUIの作成方法に完全に依存します!
[明確にするために:私はこれを達成することを知っていますが、UIの実現方法(Java Swing、コマンドライン、Webベースなど)に応じて独立して実行したいと思います]

つまり、ビジネスレイヤーはユーザーイベント/インタラクションをキャッチできない(そしてimoすべきではない)のでSession、GUIパッケージ 認識し、そこから使用する必要があります。私のデザインでは、レイヤーは厳密に下位レイヤーのインターフェイスとのみ対話する必要があります。より高いレベルについては何も知らないはずです(データアクセス層は独立しています(DBやその他の永続化メカニズムに依存します)。ビジネス層はデータアクセス層のインターフェイスにのみ依存し、プレゼンテーション層はビジネス層のインターフェイスにのみ依存します)。

問題は、プレゼンテーション層のビジネスロジック要件であると私が考えるものの一部を理解するのは間違っているように聞こえることです。

ところで、セッションの期限切れは、ユーザー入力を「リッスン」する必要があるため、おそらくプレゼンテーションロジックにあまりにも多くのことをしなければなりません。

これは、私がしばらく前に自分自身に答えた別の適切な質問を思い出させますが、疑いを避けるためにこれも質問します:質問へのリンク

主に優れた設計手法に焦点を当てた、メリットのある意見を聞きたいと思います。

4

3 に答える 3

1

要件が言うように

ログインしたユーザーが 30 分以上アイドル状態の場合、ログアウトする必要があります。

したがって、ここでの入力はキーボードまたはマウスのアクティビティです。もちろん、これはプレゼンテーション層に属します。

Web アプリケーションのシナリオでは、マウス/キーボード アクティビティ (ユーティリティ) モジュールがセッション タイムアウトをトリガーします。

Observer/Listener パターンを使用できます。ジャバなら

http://www.vogella.com/articles/DesignPatternObserver/article.htmlが参考になります

httpsession リスナーを使用して、このアクティビティをビジネス層に渡すことができます。つまり、ビジネス レイヤー機能を呼び出してクリーンアップを行うことができます。

デスクトップ シナリオでは、同様のパターンを使用できる Swing アプリケーションを使用できます。

つまり、重要なのは、ユーティリティ クラスによって提供される入力に基づいて、プレゼンテーション レイヤーが他のレイヤーに通知することです。

于 2012-09-14T11:28:18.273 に答える
0

両方。

ビジネス層は、何らかのユーザー アクティビティがあったことを知る必要があるだけです。そのアクティビティが何であるか、またはそのアクティビティがどのようにトリガーされたか (またはどこから来たか) を必ずしも知る必要はありません。

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

プレゼンテーション レイヤーがなんらかの入力 (マウスの動き、マウス クリック、キーの押下など) を受け取るたびに、そのレイヤー内のオブジェクトは、何かが発生したことをビジネス レイヤーに通知します。

物事を分離しておくために、おそらくいくつかのイベントを 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);
    }
    ....
}

そうすれば、Session オブジェクトがセッションを期限切れにする (または期限切れになろうとしている) ときに、それぞれのイベントのすべてのイベント ハンドラーをループして呼び出すことができます。これにより、レイヤーを別々に保つことができます。

于 2015-11-20T22:56:54.393 に答える