私は非常に畳み込まれていると感じるコードを書いています。畳み込みコードを暗黙的に簡略化
私は、特性である引数を受け入れるAPIを持っています。この形質は、多くのタイプによって実施することができる。さらに、これらのクラスのそれぞれは、特殊なプロセッサによって処理される必要があります。
例えば、以下の2つの実際のタイプのMobileContextとWebContextを持つContextという名前のTraitを作成しました。
MobileContextとWebContextが別にログに記録され、ContextWriter [MobileContext]とContextWriter [WebContext]という形式の特殊な実装があるとします。
このメソッドは汎用である必要がありますが、実際の型の特性に応じて適切なContextWriterへの呼び出しをディスパッチできる必要があります。
ここに私のコードです。
trait Context
case class WebContext(name: String) extends Context
case class MobileContext(name: String) extends Context
trait ContextWriter[T] {
def log(message: String, context: T) : Unit
}
object ContextWriterUtil {
def log[T](message: String, context: T)(implicit writer: ContextWriter[T]) = {
writer.log(message, context)
}
}
object ContextWriterImplicits {
implicit val webImpl = new ContextWriter[WebContext] {
override def log(message: String, context: WebContext) = println(s"I am in web context ${context} and the message is ${message}")
}
implicit val mobileImpl = new ContextWriter[MobileContext] {
override def log(message: String, context: MobileContext) = println(s"I am in mobile context ${context} and the message is ${message}")
}
implicit val baseImpl = new ContextWriter[Context] {
override def log(message: String, context: Context) = context match {
case s: WebContext => {
val writer = implicitly[ContextWriter[WebContext]]
writer.log(message, s)
}
case s: MobileContext => {
val writer = implicitly[ContextWriter[MobileContext]]
writer.log(message, s)
}
case _ => throw new Exception("don't understand this type")
}
}
}
import ContextWriterImplicits._
object MyApplication extends App {
// this is the generic method.
def call[T <: Context](message: String)(implicit context: T) = {
val actualContext = implicitly[Context]
ContextWriterUtil.log(message, actualContext)
}
def web() = {
implicit val webContext = WebContext("web")
call("I am calling the method")
}
def mobile() = {
implicit val mobileContext = MobileContext("mobile")
call("I am calling the method")
}
web()
mobile()
}
これは機能します。しかし、私はあまりにも冗長で扱いにくいと感じています。私はよりクリーンな方法でこれを記述したいと思います。