2013-07-06 77 views
2

這裏改進的通用參數是HTTP客戶端的簡單化我目前工作:與反思

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,因此我不想再指定它。

回答

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

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 _)