2012-05-07 16 views
5

Estamos usando cuarzo (la API de Java) para la programación de trabajos. Esto funciona bien Ahora estoy tratando de generalizar algunas cosas con eso. La API de cuarzo requiere una clase de trabajo como parámetro que amplía la interfaz de trabajo. Esto hace que sea imposible pasar argumentos a través de un constructor.Scala: Cree una clase de trabajo de Quartz genérica

Tenemos un conjunto de puestos de trabajo que todos deben hacer lo mismo, ejecutar un cheque, si es cierto entonces invocar una acción, por ejemplo:

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

se instancia a continuación Un trabajo de cuarzo mediante la invocación:

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

Esto funciona.

los objetivos es volver a utilizar esta lógica para diferentes tipos de cheques Pregunta: ¿Puedo utilizar el sistema de tipos Scala de tal manera que pueda tener uno JobClass mecanografiado que se puede volver a utilizar para ejecutar cualquier subclase de ¿Comprobar?

se me ha ocurrido con la siguiente solución:

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

un trabajo ahora se pueden crear instancias de esta manera:

newJob(classOf[GenericJobRule[PerformanceCheck]]) 

Esto funciona, sin embargo creo que la creación de instancias y emitan tipo de elude toda la idea de la verificación de tipos. ¿Hay alguna forma mejor de hacer esto? Tal vez deberíamos replantear nuestro diseño, así ...

Gracias, Albert

Respuesta

3

Tal vez una posibilidad es utilizar el tipo clases. Traté de ponerlo en práctica (simplificado algunas cosas), el inconveniente es que las reglas específicas del trabajo siempre se deben poner en práctica el método doCheck (para más información sobre las clases de tipos, consulte here y here):

[EDIT]: reemplazó la clase abstracta por rasgo. Ya no se necesita ningún argumento de constructor.

[EDIT2]: Olvídese de las clases de tipos (en este caso). Lo hizo mucho más simple ahora. Solo un rasgo y una clase de implementación por cheque. ¿Qué piensa usted de eso?

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 
} 

un trabajo ahora se pueden crear instancias de esta manera:

newJob(classOf[JobRule1]) 

[Edit3]: Aquí hay otra posibilidad si GenericJobRule es una clase abstracta:

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

A continuación, puede cree las reglas de trabajo específicas sobre la marcha:

val myJobRule = new GenericJobRule[SimpleCheck] { override val genericCheck = new SimpleCheck } 
+0

Veo a dónde va. Parece que JobRule1 toma un argumento constructor que no está permitido para la API de cuarzo (que debe tener un tipo de clase de constructor por defecto cero extendiendo Job. ¿O me está faltando el punto y es el objeto implícito el que se ocupa de eso? – Albert

+0

Lo hice desconozco esta restricción en la API de cuarzo (definí mis propias clases para que compile).Creo que la implementación propuesta consiste en demasiados códigos, tal vez pueda mejorarlos (y deshacerme del argumento constructor). – Christian

+0

FYI: el método de fábrica de cuarzo jobBuilder: público estático JobBuilder newJob (Clase jobClass) (gracias por cierto!) – Albert

Cuestiones relacionadas