5

我们使用quartz(java API)进行作业调度。这很好用。现在我试图用它概括一些事情。石英 api 需要一个作业类作为扩展作业接口的参数。这使得通过构造函数传递参数成为不可能。

我们有一组作业都应该做同样的事情,执行检查,如果为真则调用一个动作,例如:

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
  }
}

然后通过调用来实例化一个石英作业:

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

这行得通。

目标是为不同类型的检查重用这个逻辑问题:我可以使用 scala 类型系统,这样我就可以拥有一个类型化的 JobClass,它可以被重用于执行 Check 的任何子类?

我想出了以下解决方案:

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

也许一种可能性是使用类型类。我试图实现它(简化了一些事情),缺点是特定的作业规则总是必须实现 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 回答