我目前使用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语句中存在大量逻辑。
答案 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
时注入应该考虑使用的解析器。如果这没用,那就像以前一样静态地将它们链接在一起。
我不知道您的输入和输出类型是什么,因此我推测它们是Input
和Output
。如果你要离开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
}