1

私は、タスクの概念を持つフレームワークに取り組んでいます。多くの人がタスクを作成することを期待しており、そのためには Task インターフェースを実装するだけで済みます。タスクは名前でトリガーする必要があります。つまり、どこかにタスク名->タスククラスの中央レジストリが必要です。現在、これを行うために列挙型を使用していますが、これには、タスクの実装者が実装するすべてのタスクの列挙型にコードを追加する必要があります。これは総量です。

私が思いついた別のオプションは、Task インターフェイスを実装するすべてのクラスをリフレクションを介して検索し、そこから登録することです。これはまた、私にはひどいものであり、もっと良い方法があるに違いないと感じています。

静的イニシャライザは、実行前にクラスを少なくとも 1 回参照する必要がない場合に最適です。

注釈は別のオプションですが、ディスパッチャーを作成するためにコンパイル時に code-gen を実行する場合は、より多くのリフレクション作業が必要になるか、ビルド プロセスを変更する必要があります。

もっと簡単なアイデアはありますか?


私が現在行っていることの簡単なバージョンを以下に示します。これは、必要な制御フローのアイデアを提供するためです (簡単にするために単一のクラスに分割されています)。

class Disp {
    interface Task {
        public String doTask();
    }

    static class HelloTask implements Task {
        public String doTask() {
            return "Hello";
        }
    }

    static class ByeTask implements Task {
        public String doTask() {
            return "Bye";
        }
    }

    static class TaskDispatcher {
        static enum Tasks {
            Hello {
                Task getTask() {
                    return new HelloTask();
                }
            },
            Bye {
                Task getTask() {
                    return new ByeTask();
                }
            };
            abstract Task getTask();
        };

        public static Task getTask(String taskName) {
            return Tasks.valueOf(taskName).getTask();
        }
    }

    public static void main(String[] args) {
        System.out.println("Hello task says: "+TaskDispatcher.getTask("Hello").doTask());
        System.out.println("Bye task says: "+TaskDispatcher.getTask("Bye").doTask());
    }

}

登録するコード (たとえば) HelloTask が HelloTask 内にのみ存在し、TaskDispatcher に漏れる必要がない場合 (実際のプロジェクトのように、これらは複数の異なるファイル)

4

4 に答える 4

1

フレームワークを使用することを恐れないでください! Spring では、ほんの数行のコードで済みます。それぞれTaskに注釈を付ける必要があり ( @ServiceSpring からのものである必要はありません)、ディスパッチャーで行う必要があるのは (コンテキストをブートストラップし、コンポーネントのスキャンを有効にした後):

class TaskDispatcher {
    @Autowired
    List<Task> tasks;

    //...
}

TaskSpring はCLASSPATH 上のすべての を自動的に見つけて、それらを挿入します。Bean/クラス名を識別子または必要なものとして使用できます。

于 2012-10-28T14:23:47.240 に答える
0

たとえば、このSO投稿で、サービスプロバイダーのメカニズムを確認できます。Taskこれを使用すると、 の実装者が、実装するすべてのタスクについて中央のコード部分に通知するインターフェイスを作成できます。

私は、各実装者が独自の JAR を提供すると想定しています。この手法は、そのようなシナリオを想定しています。

于 2012-10-28T14:24:11.777 に答える
0

名前からクラス名へのマッピングを含む構成ファイルを作成するだけで、過去にこの種のことを実装しました。

Task1=com.acme.tasks.MyTask1
Task2=com.acme.tasks.more.MyTask2

これは、レジストリにデータを入力するために使用されます。その後、クラス名で実行class.forName()し、特定のタスク クラスの新しいインスタンスを作成できます。

新しいタスクを追加すると、新しいタスク クラスがクラスパスに追加され、構成ファイルに行が追加されます。既存のコードを再コンパイルする必要はありません。

于 2012-10-28T14:21:36.447 に答える