scala - 将 Function1 序列化到数据库

标签 scala serialization plugins

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

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

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/

相关文章:

javascript - jQuery AutoNumeric 不格式化多个字段

asp.net-mvc - NopCommerce 使用插件在管理区域添加额外或自定义选项卡菜单

java - Scala 中的库——在 Android 中使用

java - 从 jar 中提取 scala 源代码

java - 使用 Gson 序列化和反序列化枚举

perl - 如何在 Perl 中使用客户端和服务器传输哈希?

scala - 如何在 Scala 中使用 >=>?

spring - 在 Scala 中使用 Spring @Transactional

c++ - 使用 ZMQ 和 protobuf 时收到 0 大小的消息

javascript - Jquery Apprise 插件无法正常工作