2012-01-12 36 views
3

我知道它不是直接可能序列化函數/匿名類到數據庫,但有什麼選擇?你知道任何有用的方法嗎?序列化函數1到數據庫

介紹我的情況:我要評選基於他的分數用戶「徽章」。所以,我有不同類型的徽章可以通過擴展該類輕鬆定義:

class BadgeType(id:Long, name:String, detector:Function1[List[UserScore],Boolean]) 

的檢測器構件是走分數的列表,如果用戶有資格獲得這種類型的徽章返回true的功能。

的問題是,我想每次添加/編輯/修改徽章型我需要修改源代碼,重新編譯整個事情,重新部署服務器。如果我可以將所有BadgeType實例持久化到數據庫,那將會更有用。但如何做到這一點?

,想到的唯一的事情是有函數體作爲腳本(例如:Groovy中),在運行時計算。

另一種方法(不包括數據庫)可能是讓每個徽章類型到一個罐子,我能以某種方式在運行時熱部署,我的猜測是一個插件,系統會如何運作。

您認爲如何?

+3

我覺得怎麼樣?我想你應該問一個比「你認爲怎樣?」更具體的問題。 – Malvolio 2012-01-12 18:43:09

+0

@Malvolio我認爲很明顯,最後一行只是對我在開始時足夠清楚地表達的實際問題的強調:「有什麼選擇?你知道有什麼有用的方法嗎?」在交流中不要重複自己,這是一個常見的習慣用法。看起來其他人的確更仔細地閱讀了這個問題,因爲我確實得到了一些很好的答案。 – 2012-01-13 09:14:21

回答

3

我非常簡要的建議是,如果你想這是真正的數據驅動的,你需要實現一個規則DSL和一名翻譯。規則是保存到數據庫的內容,解釋器接受規則實例並根據某個上下文對其進行評估。

但是這在大多數情況下是過度的。你最好有一小段實際的Scala代碼實現每個徽章的規則,爲他們提供唯一的ID,然後將這些ID存儲在數據庫中。

如:

trait BadgeEval extends Function1[User,Boolean] { 
    def badgeId: Int 
} 

object Badge1234 extends BadgeEval { 
    def badgeId = 1234 
    def apply(user: User) = { 
    user.isSufficientlyAwesome // && ... 
    } 
} 

您可以有BadgeEval實例的大白名單:

val weDontNeedNoStinkingBadges = Map(
    1234 -> Badge1234, 
    5678 -> Badge5678, 
    // ... 
} 

def evaluator(id: Int): Option[BadgeEval] = weDontNeedNoStinkingBadges.get(id) 

def doesUserGetBadge(user: User, id: Int) = evaluator(id).map(_(user)).getOrElse(false) 

...或者,如果你想保持他們分離,使用反射:

def badgeEvalClass(id: Int) = Class.forName("com.example.badge.Badge" + id + "$").asInstanceOf[Class[BadgeEval]] 

...如果你有興趣在運行時可插,嘗試service provider pattern

+0

感謝您的好評!第一部分就是我現在所擁有的,但並不能解決這個事實,即當我想要一個新的徽章類型時,我需要重新編譯整個事物。服務提供商是我一直在尋找的東西。我想在同樣的思路下,自定義的ClassLoader就足夠了,以防實現起來更簡單。 – 2012-01-13 10:07:43

0

序列化涉及數據而不是方法。你不能序列化功能,因爲它是一個類文件,用於序列化序列化對象序列化序列化對象的字段。

就像Alex說的那樣,你需要一個規則引擎。

,如果你想要的東西很簡單,它是基於字符串試試這一個,所以你可以序列化的規則,在數據庫中的字符串或文件:

http://blog.maxant.co.uk/pebble/2011/11/12/1321129560000.html

使用DSL具有除非同樣的問題您在運行時解釋或編譯代碼。