サービスについてどれだけ多くの仮定を立てることができるか、または喜んで行うかにもよりますが、オプションになる可能性のあるまったく単純なアプローチを次に示します。基本的には、1) 考えられるすべてのメッセージ タイプが既知であること、および b) 部分関数が 1 つの次元でのみ部分的であること (詳細は後述) に依存しています。
可能なメッセージ タイプの有限セットが必要です。
sealed trait Message
case class Hello(who: String) extends Message
case class Lunch(withWhom: String) extends Message
case class Dinner(withWhom: String) extends Message
case class Goodbye(who: String) extends Message
そして、いくつかのサービス例:
val service0: PartialFunction[Any, Unit] = {
case Hello(who) => ()
case Goodbye(who) => ()
}
val service1: PartialFunction[Any, Unit] = {
case Hello(who) => ()
case Lunch(withWhom) => ()
case Goodbye(who) => ()
}
var services = List(service0, service1)
次に、受け入れられたメッセージの設計図として機能するメッセージ インスタンスのリストも定義します。
val simpleInstances = List(Hello("*"), Lunch("*"), Dinner("*"), Goodbye("*"))
最後に、部分関数から受け入れられた引数と可能な引数のリストを返すメソッドを定義します。
def supportedArguments[F, T, A <: F]
(pf: PartialFunction[F, T], args: Iterable[A]) =
args filter pf.isDefinedAt
きれいなプリンター:
def printSupportedArguments(services: Iterable[PartialFunction[Any, Unit]],
messages: Iterable[Message]) {
services.zipWithIndex.foreach {case (s, i) =>
val supported = supportedArguments(s, messages)
println(s"Service $i supports $supported")
}
}
さあ行こう:
printSupportedArguments(services, simpleInstances)
// Service 0 supports List(Hello(*), Goodbye(*))
// Service 1 supports List(Hello(*), Lunch(*), Goodbye(*))
// Service 2 supports List(Goodbye(*))
サービスが受け入れるメッセージ タイプに関して部分的であるだけでなく、受け入れるメッセージ コンテンツに関しても部分的である場合、つまり、サービスが複数の方向で部分的である場合、事態はさらに複雑になります。
val service2: PartialFunction[Any, Unit] = {
case Hello("Thomas") => ()
case Hello("Laura") => ()
case Goodbye(who) => ()
}
このようなサービスには、ブループリント インスタンスのリストの適応も必要です。
val moreInstances = simpleInstances ++ List(Hello("Thomas"), Hello("Laura"))
その結果:
printSupportedArguments(services :+ service2, moreInstances)
// Service 0 supports List(Hello(*), Goodbye(*), Hello(Thomas), Hello(Laura))
// Service 1 supports List(Hello(*), Lunch(*), Goodbye(*), Hello(Thomas),
// Hello(Laura))
// Service 2 supports List(Goodbye(*), Hello(Thomas), Hello(Laura))
このアプローチの一連の欠点には、明らかに次のようなものがあります。
マクロまたはリフレクション (またはマジック) を使用した実際の解決策を見つけた場合は、ここに投稿してください。