从Actor系统重构到模式匹配

时间:2016-12-19 16:13:26

标签: scala pattern-matching

我目前使用Actors:

class XmlParserActor extends Actor with XmlVersion1Schema with XmlVersion2Schema with XmlVersion3Schema {

    def recieve = xmlVersion1 orElse xmlVersion2 orElse xmlVersion3

}

trait xmlVersion1Schema { this: XmlParserActor =>

    def xmlVersion1: Receive = {
        case ...
        case ...
        case ...
    }
}

我想重构这个不使用actor,最好的方法是什么?

最直接的方法是创建一个大模式匹配,其中包含来自所有3个XmlVersionXSchema特征的所有case子句。

我是否应该考虑其他替代方案,其目的是将逻辑与其他文件分开,因为目前case语句中存在大量逻辑。

1 个答案:

答案 0 :(得分:2)

在Akka,你有type Receive = PartialFunction[Any, Unit]def recieve = xmlVersion1 orElse xmlVersion2 orElse xmlVersion3行只是使用标准库中的orElse组合子组成这些部分函数。结果只是一个更大的PartialFunction[Any, Unit]

您可以在演员之外使用相同的策略。我可能会这样做:

class FullXmlParser(parsers: PartialFunction[Input, Output]*) {
  val composedParser = parsers.foldLeft(PartialFunction.empty[Input, Output])(_ orElse _)

  def parse(input: Input): Option[Output] = composedParser.lift.apply(input)
}

这样,我可以在实例化FullParser时注入应该考虑使用的解析器。如果这没用,那就像以前一样静态地将它们链接在一起。

我不知道您的输入和输出类型是什么,因此我推测它们是InputOutput。如果你要离开Akka Land,我强烈建议收紧你的类型界限。

在Akka中,只会删除与您的任何解析器不匹配的消息。在这里,我将PartialFunction提升为返回Function1的{​​总数} Option[Output],并且处理None案例的责任在调用者身上。

然后你可以这样做:

// At setup time (application start-up, or upon configuration)
val parser = new FullXmlParser(xmlVersion1, xmlVersion2, xmlVersion3)

// At parse time
parser.parse(yourInput) match {
  case Some(output) => // whatever happens upon success
  case None         => // failure handling
}