我将Scala与AWS lambda结合使用,处理不同类型的事件。每个“处理程序”类都是一个不同的lambda处理程序,将仅用于一种类型的消息,但是为了共享通用的处理代码,我将内容汇总为抽象类+特征
当需要将特定于每种消息类型的处理移交给子类时,我最终得到了一个抽象方法,我仍然需要对消息的类型进行模式匹配,如果出现这种情况,则总是记录某种错误错误的消息类型使其变成处理程序子类型。
这些默认情况似乎是多余的,因为错误的消息类型永远不会到达错误的处理程序子类型。
这是我所拥有的简化版本
trait Message {
val text: String
}
case class MessageA(text: String, errorCode: Int) extends Message
case class MessageB(text: String, url: String) extends Message
abstract class MessageHandler {
protected def processMessage(message: Message)
...
}
//Lambda handler 1
class MessageAHandler extends MessageHandler {
override protected def processMessage(message: Message) = message match {
case a: MessageA => handleErrorCode(a.errorCode)
case _ => //log some error - This should never be reached
}
...
}
//Lambda handler 2
class MessageBHandler extends MessageHandler {
override protected def processMessage(message: Message) = message match {
case b: MessageB => handleUrl(b.url)
case _ => //log some error - This should never be reached
}
...
}
我尝试用类型限制实现processMessage
调用,但这似乎并没有太大的区别,我仍然需要在'M'上进行模式匹配以确定message参数的子类型,因此可以这样对待。
protected def processMessage[M <: Message](message: M)
有人必须做类似的事情吗?有没有更清洁的方式做到这一点?
答案 0 :(得分:0)
您可以将Message类型抽象为基本类型:
abstract class MessageHandler {
type Msg <: Message
protected def processMessage(message: Msg)
}
class MessageAHandler extends MessageHandler {
type Msg = MessageA
protected def processMessage(message: MessageA) =
handleErrorCode(message.errorCode)
}
但是我不确定从调用站点(调用processMessage
的代码)之后是否易于处理。模式匹配可能只在那儿移动(但总体上可能会更优雅)。
答案 1 :(得分:0)
您可以在此处使用继承。将代码放入特质中处理消息,然后让多态为您完成工作。
trait Message {
val text: String
def handleMessage
}
case class MessageA(text: String, errorCode: Int) extends Message
{
override def handleMessage = handleErrorCode(errorCode)
}
case class MessageB(text: String, url: String) extends Message
{
override def handleMessage = handleUrl(url)
}
case object MessageHandler
{
def processMessage(message: Message) = message.handleMessage
}