gpt4 book ai didi

scala - 将 Function1 序列化到数据库

转载 作者:行者123 更新时间:2023-12-04 16:00:32 25 4
gpt4 key购买 nike

我知道不能直接将函数/匿名类序列化到数据库,但有哪些替代方案?你知道有什么有用的方法吗?

介绍一下我的情况:我想根据用户的分数授予用户“徽章”。所以我有不同类型的徽章,可以通过扩展此类轻松定义:

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

检测器成员是一个函数,它遍历分数列表并在用户有资格获得这种类型的徽章时返回 true。

问题是每次我想添加/编辑/修改徽章类型时,我都需要编辑源代码,重新编译整个东西并重新部署服务器。如果我可以将所有 BadgeType 实例持久保存到数据库中,那将会更有用。但是该怎么做呢?

唯一想到的是将函数体作为在运行时评估的脚本(例如:Groovy)。

另一种方法(不涉及数据库)可能是将每个徽章类型放入一个 jar 中,我可以在运行时以某种方式热部署,我想这就是插件系统的工作方式。

你怎么看?

最佳答案

我非常简短的建议是,如果您希望它真正是数据驱动的,则需要实现规则 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 .

关于scala - 将 Function1 序列化到数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8839999/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com