我已经构建了一些像这样的代码:
“HandlerArguments”类,它将接收所有处理程序子类所需的一堆工厂和其他帮助程序:
class HandlerArguments(
val a: A,
val b: B,
val c: C) {
/* nothing here */
}
将使用HandlerArguments的Handler超类:
class Handler(val args: HandlerArguments) {
def subHandler1 = new SubHandler1(args)
def subHandler2 = new SubHandler2(args)
def subHandler3 = new SubHandler3(args)
var message: Message = null
/* code here that invokes subHandler1, 2, or 3 based on a matcher */
def invokeCommand(msg: Message) = {
message = msg
someCommand match {
case command1 => subHandler1.something()
case command2 => subHandler2.something()
case command3 => subHandler3.something()
}
}
}
subHandlers或subClasses:
class subHandler1(args: HandlerArguments) extends Handler(args) {
...
args.something.somethingElse(message.x)
...
}
class subHandler2(args: HandlerArguments) extends Handler(args) { ... }
class subHandler3(args: HandlerArguments) extends Handler(args) { ... }
在另一个文件中,我正在初始化Handler:
/* initializing Handler */
val args = new HandlerArguments(a, b, c)
val handler = new Handler(args)
handler.invokeCommand(someMsg)
我的问题是,
这是最好的方法吗?我想要实现的主要内容是不必在超类Handler和子类之间传递“消息”(即subHandler1.something(message))。
我如何使用HandlerArguments?我想过使用traits或抽象类,但这需要设置一次然后由Handler类使用。
我将args从Handler传递给SubHandlers似乎很奇怪,只是在extends子句中将它传递给Handler。有更好的方法吗?
思考?谢谢!
答案 0 :(得分:1)
这里有一个命令/查找表模式的例子。
我能提供的一些事情是:
将HandlerArguments
设为case class
。这样,它就会变得更加冗长,并且您可以获得许多额外的好处。
case class HandlerArguments(a: A, b: B, c: C)
你完成了。 case类构造函数的参数自动被视为vals
。
我可以看到的另一个问题是,从超类构造子类实例会导致堆栈溢出(因为子类构造也构造了一个超类实例,并且循环无限期地继续)。
但是,根据您的用例,您的Handler
和SubHandler*
类之间可能不应存在超类 - 子类关系。 subHandler*
类是实际的处理程序,也就是说,它们是处理消息的类。您的Handler
班只是向他们发送消息。你在这里可以做的事情如下:
case class HandlerArgs(a: A, b: B, c: C)
trait MessageHandler {
val args: HandlerArgs
def handle(msg: String)
}
class Handler1(val args: HandlerArgs) extends MessageHandler {
override def handle(msg: String) = ???
}
class Handler2(val args: HandlerArgs) extends MessageHandler {
override def handle(msg: String) = ???
}
class Handler3(val args: HandlerArgs) extends MessageHandler {
override def handle(msg: String) = ???
}
class MessageDispatcher(args: HandlerArgs) {
private val messageHandler1 = new Handler1(args)
private val messageHandler2 = new Handler2(args)
private val messageHandler3 = new Handler3(args)
def dispatch(message: String) {
val someCommand: Command = ???
someCommand match {
case Command("command1") => messageHandler1.handle(message)
case Command("command2") => messageHandler2.handle(message)
case Command("command3") => messageHandler3.handle(message)
}
}
}
val dispatcher = new MessageDispatcher(HandlerArgs(new A, new B, new C))
dispatcher.dispatch("<some command>")
评论后更新
如果您希望所有实例共享消息,可以选择将模板模式添加到现有代码中:
trait MessageHandler {
val args: HandlerArgs
private var message: Option[String] = None
// Save the message in a common implementation, and...
private def saveMessage(msg: String) {
message = Option(msg)
}
def handle(msg: String) {
saveMessage(msg)
doSomethingWithMessage(msg)
}
// let the subclasses handle the the actual message handling
protected def doSomethingWithMessage(msg: String)
}
class Handler1(val args: HandlerArgs) extends MessageHandler {
override def doSomethingWithMessage(msg: String) = ???
}
// rest of the message handlers
当然,有几种方法可以做到这一点。
另一种方式,如评论中所讨论的,是使用单个元素容器。对于前。
class MessageHolder {
var message: Option[String] = None
}
trait MessageHandler {
val args: HandlerArgs
val messageHolder: MessageHolder
def handle(msg: String)
}
class Handler1(val args: HandlerArgs,
val messageHolder: MessageHolder) extends MessageHandler {
override def handle(msg: String) = ???
}
class MessageDispatcher(args: HandlerArgs) {
private val mh = new MessageHolder
private val messageHandler1 = new Handler1(args, mh)
private val messageHandler2 = new Handler2(args, mh)
private val messageHandler3 = new Handler3(args, mh)
def dispatch(message: String) {
val someCommand: Command = ???
mh.message = Option(message)
// ...
}
}