2012-05-07 4 views
5

Utilizziamo il quarzo (l'API java) per la pianificazione del lavoro. Funziona bene Ora sto cercando di generalizzare alcune cose con esso. Il quarzo api richiede una classe di lavoro come parametro che estende l'interfaccia di lavoro. Questo rende impossibile passare argomenti tramite un costruttore.Scala: Crea una classe di lavoro Quartz generica

abbiamo una serie di posti di lavoro che tutti dovrebbero fare lo stesso, eseguire un controllo, se è vero quindi richiamare un'azione, ad esempio:

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

Un lavoro di quarzo viene poi creata un'istanza invocando:

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

Questo funziona.

L'obiettivo è riutilizzare questa logica per diversi tipi di controlli Domanda: Posso usare il sistema di tipo scala in modo tale che possa avere un JobClass digitato che può essere riutilizzato per eseguire qualsiasi sottoclasse di Dai un'occhiata?

mi è venuta in mente la seguente soluzione:

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 lavoro può ora essere un'istanza in questo modo:

newJob(classOf[GenericJobRule[PerformanceCheck]]) 

Questo funziona, tuttavia credo che la creazione di istanze e la colata tipo-di ignora l'intera idea di controllo dei caratteri. C'è un modo migliore per farlo? Forse dovremmo ripensare il nostro design e ...

Grazie, Albert

risposta

3

Forse un possibilty è quello di utilizzare le classi di tipo. Ho cercato per la sua attuazione (semplificato alcune cose), il lato negativo è che le regole di lavoro specifiche sempre devono implementare il metodo doCheck (per maggiori informazioni su classi di tipo, vedere here e here):

[EDIT]: sostituito classe astratta per tratto. Nessun argomento del costruttore è più necessario.

[EDIT2]: dimenticare le classi di tipi (in questo caso). Lo ha reso molto più semplice ora. Solo un tratto e una classe di implementazione per assegno. Cosa ne pensi?

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 lavoro può ora essere un'istanza in questo modo:

newJob(classOf[JobRule1]) 

[Edit3]: Ecco un'altra possibilità se GenericJobRule è una classe astratta:

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

Poi si può creare al volo le regole specifiche del lavoro:

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

Vedo dove stai andando. Sembra che JobRule1 prenda un argomento costruttore che non è consentito per l'API quarzata (che deve avere un tipo di classe di costruttore di default zero est che estende Job. O mi manca il punto e l'oggetto implicito si sta occupando di quello? – Albert

+0

Ho fatto non so di questa restrizione in quarzo API (ho definito le mie classi in modo che compili).Penso che la mia proposta di implementazione consista in un numero eccessivo di codice, forse potrò migliorarla (e liberarmi dell'argomento del costruttore). – Christian

+0

FYI: il lavoro al quarzo Metodo costruttore di fabbrica: public static JobBuilder newJob (Classe jobClass) (grazie ancora!) – Albert