2012-05-07 15 views
5

Używamy kwarcu (API Java) do planowania zadań. To działa dobrze. Teraz próbuję uogólnić niektóre rzeczy. Kwarc api wymaga klasy zadania jako parametru, który rozszerza interfejs Job. To uniemożliwia przekazywanie argumentów za pośrednictwem konstruktora.Scala: Stwórz ogólną pracę Quartz Job

Mamy zestaw zadań, które powinny wszystko to samo, wykonać test, jeśli jest prawdziwa wtedy wywołać akcję, na przykład:

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

Zadanie kwarc jest następnie instancja powołując:

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

To działa.

Celem jest ponowne wykorzystanie tej logiki dla różnych typów kontroli. Pytanie: Czy mogę używać systemu typu scala w taki sposób, że mogę mieć jeden wpisany JobClass, który może być ponownie użyty do wykonania dowolnej podklasy Czek?

mam wymyślić następujące rozwiązanie:

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

Zadanie może być teraz instancja tak:

newJob(classOf[GenericJobRule[PerformanceCheck]]) 

To działa, jednak myślę, że instancji i rzucając na rodzaj omija całą koncepcję sprawdzania typu. Czy istnieje lepszy sposób to zrobić? Może powinniśmy przemyśleć nasze projekty, jak również ...

Dzięki Albert

Odpowiedz

3

Może jeden possibilty jest użycie klasy typu. Próbowałem go (uproszczony kilka rzeczy), minusem jest że szczególne zasady pracy zawsze musi implementować metodę doCheck (więcej o zajęciach typu, patrz here i here) realizują:

[EDIT]: zastąpił klasę abstrakcyjną cechą. Żaden argument konstruktora nie jest już potrzebny.

[EDIT2]: Zapomnij o klasach typów (w tym przypadku). Teraz stało się to znacznie prostsze. Tylko cecha i klasa wykonawcza na czek. Co o tym myślisz?

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 
} 

Zadanie może być teraz instancja tak:

newJob(classOf[JobRule1]) 

[Edit3]: Oto kolejna możliwość, jeśli GenericJobRule jest klasą abstrakcyjną:

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

Następnie można stwórz szczegółowe reguły pracy w locie:

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

Widzę, dokąd zmierzasz. Wygląda na to, że JobRule1 przyjmuje argument konstruktora, który nie jest dozwolony dla kwarcowego API (który musi mieć domyślny typ klasy konstruktora zera, rozszerzający Job) lub czy brakuje mi tego punktu i czy jest to niejawny obiekt, który o to dba? – Albert

+0

nie znam tego ograniczenia w API kwarcu (zdefiniowałem własne klasy, więc się kompiluje).Myślę, że moja proponowana implementacja składa się z zbyt wielu kodów, może uda mi się ją poprawić (i pozbyć się argumentu konstruktora). – Christian

+0

FYI: Metoda fabryka kwarcowy jobBuilder: public static JobBuilder newJob (klasa jobClass) (dzięki btw do tej pory!) – Albert

Powiązane problemy