2012-05-07 84 views
5

我們使用quartz(java API)進行作業調度。這很好。現在我試圖用它概括一些事情。石英api需要一個作業類作爲擴展Job界面的參數。這使得通過構造函數傳遞參數成爲不可能。Scala:創建一個通用的Quartz 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 
    } 
} 

石英的工作就是實例化,通過調用:

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

這是有效的。

的目標是重新使用此邏輯用於不同類型的檢查 問題:能否用階式系統中,使得我可以有一個輸入JobClass其可以被重新使用來執行的任何亞類的方式檢查?

我已經想出了以下解決方案:

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]]) 

這工作,但我認爲實例化和鑄造一種-的繞過了類型檢查的整個想法。有沒有更好的方法來做到這一點?也許我們應該重新思考我們的設計,以及...

感謝,阿爾伯特

回答

3

也許一個possibilty是使用類型類。我試圖實現它(簡化了一些東西),壞處是 ,具體的工作規則,必須始終貫徹doCheck方法(關於類型類,見herehere):

[編輯]:以特質取代抽象類。不再需要構造函數參數。

[編輯2]:忘記類型類(在這種情況下)。現在變得更簡單了。每支支票只是一個特質和一個實施班。你對那個怎麼想的?

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

我明白你要去的地方。看起來像JobRule1需要一個構造函數參數,這是不允許的石英API(它必須有一個零參數默認構造函數類類型擴展作業。或者我錯過了這一點,是隱含的對象照顧? – Albert

+0

我做了不知道石英API中的這個限制(我定義了我自己的類,因此它編譯)。我認爲我提出的實現包含了太多的代碼,也許我可以改進它(並且擺脫構造函數參數)。 – Christian

+0

FYI:石英jobBuilder工廠方法: public static JobBuilder newJob(Class <?extends Job> jobClass) (謝謝btw到目前爲止!) – Albert