2

私が望むものを達成するためのより良い代替方法がある場合に備えて、以下に私の目標の簡単な概要を示します. この質問は私が必要とするものと非常に似ていますが、私が必要とするものとはまったく異なります。私の質問...

私はインターフェースを持っています:

public interface Command<T> extends Serializable {}

..さらに実装:

public class EchoCommand implements Command<String> {
    private final String stringToEcho;

    public EchoCommand(String stringToEcho) {
        this.stringToEcho = stringToEcho;
    }

    public String getStringToEcho() {
        return stringToEcho;
    }
}

別のインターフェイスを作成する場合:

public interface AuthorizedCommand {
    String getAuthorizedUser();
}

..サブクラスの型を知らなくても、実行時に EchoCommand に AuthorizedCommand インターフェイスを実装する方法はありますか?

public <C extends Command<T>,T> C authorize(C command) {
    // can this be done so the returned Command is also an
    // instance of AuthorizedCommand?
    return (C) theDecoratedCommand;
}

その理由は... 私は Netty を使用して、コマンドに基づく非常に単純な概念実証用のクライアント/サーバー フレームワークを自分自身で構築しました。クライアントとサーバー間で共有されるコマンドとコマンド ハンドラーの間には、1 対 1 の関係があります。ハンドラーはサーバー上にのみあり、実装は非常に簡単です。これがインターフェースです。

public interface CommandHandler<C extends Command<T>,T> {
    public T execute(C command);
}

クライアント側でも、物事は非常に単純です。コマンド ベースの API を試すことにした主な理由は、クライアントで物事をシンプルに保つことです。クライアントはコマンドをディスパッチし、Future を取得します。呼び出しが非同期であることは明らかであり、クライアントは呼び出しを でラップするなどの処理を行いませんSwingWorker。同期呼び出しを非同期ヘルパー メソッドでラップするためだけに、非同期呼び出し (ネットワーク上のあらゆるもの) に対して同期 API を構築するのはなぜですか? これにはグアバを使用しています。

public <T> ListenableFuture<T> dispatch(Command<T> command)

次に、認証と承認を追加します。コマンドハンドラーに許可について強制的に知らせたくはありませんが、場合によっては、コマンドが実行されているユーザーに関して何かを問い合わせることができるようにしたいと考えています。lastModifiedBy主に、いくつかのデータに属性を持たせたいと思っています。

私は Apache Shiro の使用を検討しているので、明らかな答えはそれらを使用しSubjectAwareExecutorて認証情報を に取得することのようですThreadLocalが、その場合、私のハンドラーは Shiro を認識している必要があります。 Shiro の認証/承認情報。

各 Command は既に状態を保持しており、パイプライン全体を通過しているため、AuthorizedCommand インターフェースを実装するように承認済みのコマンドをデコレートするだけで作業がはるかに簡単になります。その後、コマンド ハンドラーは装飾された情報を使用できますが、これは完全にオプションです。

if(command instanceof AuthorizedCommand) {
    // We can interrogate the command for the extra meta data
    // we're interested in.
}

そうすれば、アプリケーションのコア ビジネス ロジックとは無関係に、認証/承認に関連するすべてを開発することもできます。また、(私が思うに) セッション情報を Netty に関連付けChannelたりChannelGroup、NIO フレームワークにとってより理にかなっていると思いますよね? Netty 4 では、Channelセッション情報などを追跡するのに適していると思われる に型付き属性を設定することもできると思います (ただし、調べていません)。

私が達成したい主なことは、アプリケーションのプロトタイプを非常に迅速に構築できるようにすることです。コマンドタイプからコマンドハンドラーへの単純なマップであり、ネットワークとセキュリティの側面を完全に無視するクライアント側のディスパッチャーから始めたいと思います。プロトタイプに満足したら、(Guice を使用して) Netty ベースのディスパッチャに交換し、開発サイクルの非常に遅い段階で Shiro を追加します。

コメントや建設的な批判をいただければ幸いです。私が説明したことが理にかなっていて、単純な古い Java では不可能な場合は、その特定の機能を別の JVM 言語で構築することを検討します。もしかしてスカラ?

4

1 に答える 1

0

次のようなことを試すことができます。

Java: 実行時のクラスの拡張

実行時に、コードはコマンドのクラスを拡張してインスタンス化し、AuthorizedCommand インターフェイスを実装します。これにより、元の Command クラス構造を保持しながら、クラスが AuthorizedCommand のインスタンスになります。

注意すべきことの 1 つは、「final」キーワードを使用してクラスを拡張できないことです。

于 2013-06-18T12:56:53.757 に答える