以下是我正在处理的Http-Client的简化:
class Request[A]( val url: String, val event: Callbacks[A] )
{
def run: Try[A] = ...
}
case class Image( override val url: String, override val event: Callbacks[Bitmap] ) extends Request[Bitmap]
object GET
{
def apply[A <: Request[B] : ClassTag, B : ClassTag]( url: String, event: Callbacks[B] ): Try[B] =
{
classOf[A]
.runtimeClass
.getConstructor( classOf[String], classOf[Callbacks[B]] )
.newInstance( url, event )
.asInstanceOf[A]
.run
}
}
object Main extends App
{
GET[Image, Bitmap]( "http://...", null )
}
我想改进我的API,以便我可以像这样进行GET
调用:
GET[Image]( "http://...", null )
提供通用参数Image
应该意味着我正在使用Bitmap
,因此我不想再指定它。
答案 0 :(得分:1)
您可以使用类似于CanBuildFrom
的模式:使用隐式构建器创建合适的Request
:
某些类型:
abstract class Content
class Bitmap extends Content
class Callbacks[T]
abstract class Request[C <: Content](val url: String, val event: Callbacks[C]) {
def run: C
}
class ImageRequest(_url: String, _event: Callbacks[Bitmap])
extends Request[Bitmap](_url, _event) {
def run: Bitmap = {
new Bitmap()
}
}
现在是隐式参数RequestBuilder
的类型:
abstract class RequestBuilder[C <: Content] {
def create(url: String, event: Callbacks[C]): Request[C]
}
class ImageRequestBuilder extends RequestBuilder[Bitmap]() {
def create(url: String, event: Callbacks[Bitmap]): ImageRequest = {
new ImageRequest(url, event)
}
}
object ImplicitContainer {
implicit val ImplicitImageRequestBuilder = new ImageRequestBuilder()
}
这样使用:
object GET {
def apply[C <: Content](url: String, event: Callbacks[C])
(implicit rb: RequestBuilder[C]): C = {
rb.create(url, event).run
}
}
object HttpClient extends App {
import ImplicitContainer._
val bitmap = GET[Bitmap]("http://...", null)
println(bitmap)
}
这样,当您致电GET
时,您始终会收到不同的请求。
答案 1 :(得分:0)
我能得到的最接近的是提供一个隐式参数,并将所有结果映射器(Image,Html,...)注册为隐式值。由于额外的隐式定义,这会增加一些配置开销,但会产生更好的自定义优势。这样我也摆脱了反射部分。
implicit val image = Image.apply _
object GET
{
def apply[T]( url: String, event: Callbacks[T] )( implicit request: ( String, Callbacks[T] ) => Request[T] ): Try[T] =
{
request( url, event ).run
}
}
import image
GET[Bitmap]( "http://...", null )
GET[Bitmap]( "http://...", null )( myOwnAwesomeImageProcessor _ )