5

ジョブのスケジューリングには Quartz (Java API) を使用しています。これはうまくいきます。今、私はいくつかのことを一般化しようとしています。Quartz API には、Job インターフェースを拡張するパラメーターとしてジョブ クラスが必要です。これにより、コンストラクターを介して引数を渡すことができなくなります。

すべて同じことを行い、チェックを実行し、true の場合はアクションを呼び出す一連のジョブがあります。次に例を示します。

class SimpleJob extends Job {

def execute(context: JobExecutionContext) {
  val check = classOf[SimpleCheck].asInstanceOf[Class[Check]].newInstance()
  val result = check.execute(context.getJobDetail.getJobDataMap)

  if (result.shouldInvokeAction) {
    Action(result).execute
  }
}

Quartz ジョブは、次の呼び出しによってインスタンス化されます。

newJob(classOf[SimpleJob]).with...

これは機能します。

目標は、このロジックをさまざまなタイプのチェックに再利用することです 質問: Check の任意のサブクラスを実行するために再利用できる 1 つの型付き JobClass を持つことができるような方法で、scala 型システムを使用できますか?

私は次の解決策を思いつきました:

class GenericJobRule[J <: Check](implicit m: Manifest[J]) extends Job {

  def execute(context: JobExecutionContext) {
    val check = m.erasure.newInstance().asInstanceOf[J]
    val result = check.execute(context.getJobDetail.getJobDataMap)

    if (result.shouldInvokeAction) {
      Action(result).execute
    }
  }
}

ジョブは次のようにインスタンス化できるようになりました:

newJob(classOf[GenericJobRule[PerformanceCheck]])

これは機能しますが、インスタンス化とキャストは、タイプチェックのアイデア全体をバイパスしていると思います。これを行うより良い方法はありますか?デザインも考え直した方がいいのかな…

ありがとう、アルバート

4

1 に答える 1

3

おそらく、1 つの可能性は型クラスを使用することです。私はそれを実装しようとしました(いくつかのことを簡略化しました)。欠点は、特定のジョブルールが常に doCheck メソッドを実装する必要があることです(型クラスの詳細については、こちらこちらを参照してください):

[編集] : 抽象クラスを特性に置き換えました。コンストラクターの引数はもう必要ありません。

[EDIT2] : 型クラスのことは忘れてください (この場合)。よりシンプルになりました。チェックごとの単なる特性と実装クラス。それについてどう思いますか?

trait GenericJobRule[J <: Check] extends Job {

  val genericCheck: J

  def execute(context: JobExecutionContext) {
    val result = genericCheck.execute(context.getJobDataMap)

    if (result.shouldInvokeAction) {
      Action(result).execute
    }
  }  
}

class JobRule1 extends GenericJobRule[SimpleCheck] {
  override val genericCheck = new SimpleCheck
}

ジョブは次のようにインスタンス化できるようになりました:

newJob(classOf[JobRule1])

[EDIT3] : GenericJobRule が抽象クラスの場合、別の可能性があります。

abstract class GenericJobRule[J <: Check] extends Job {

  val genericCheck: J

  def execute(context: JobExecutionContext) {
    val result = genericCheck.execute(context.getJobDataMap)

    if (result.shouldInvokeAction) {
      Action(result).execute
    }
  }  
}

次に、特定のジョブ ルールをオンザフライで作成できます。

val myJobRule = new GenericJobRule[SimpleCheck] { override val genericCheck = new SimpleCheck }
于 2012-05-07T14:01:30.123 に答える