2013-04-01 39 views
3

我正在構建具有驚人數量抽象的ubercool應用程序。 現在我要設計過度設計的EntityGetService。選項和未來

我想的第一件事是很多抽象類,讓說,這樣的事情:這裏

trait EntityGetService[ID, ENTITY, CONTAINER] { 
    def get(id: ID): CONTAINER 
} 

容器的東西,包含(或不包含)鍵入所需的實體。與選項[ENTITY]非常相似。但是我想要的第二件事,那就是CONTAINER也可以成爲未來[ENTITY]。

所以我真的想寫特點是這樣的:

trait EntityGetService[ID, ENTITY, CONTAINER <: Wrapper[ENTITY]] { 
    def get(id: ID): CONTAINER 
} 

,在這種方式指定它:

trait EntitySyncGetService[Long, Entity, Option[Entity]] { 
    def get(id: Long): Option[Entity] 
} 

trait EntityAsyncGetService[Long, Entity, Future[Entity]] { 
    def get(id: Long): Future[Entity] 
} 

有沒有辦法做到這一點,而無需重新延長或混合的東西期權和未來?

它看起來像期權和未來有一點共同的(他們兩個集裝箱)。這與單子有關嗎?

還是這只是一個我的失眠的產品?

回答

3

不評論這一切的合理性,可以使用更高階的類型:

trait WrappedGetService[ID, ENTITY, WRAPPER[_]] { 
    def get(id: ID) : WRAPPER[ENTITY] 
} 

,那麼你可以聲明WrappedGetService[Long, Entity, Option]

更新:一些參考

該功能被稱爲高階類型(可能更高kinded類型太)或類型的構造函數

  • the language specification,它應該出現主要是在部分 4.4,類型參數,但不會有很多關於它,它的工作原理就像其他類型的參數。
  • 的功能在紙Generics of a higher kind紙張可能無法精確地實現爲在 語言最初提出的,但它應該是非常接近的。另一方面,收藏品庫又是另一種方式,您可能會在Fighting Bit Rot with Types中看到爲什麼。
  • 你可能會看看scalaz庫(不適合心臟不好)。如果你這樣做,你可能也想看看Haskell。
+0

看起來像這是我正在尋找。你能指出一些資源來閱讀這個功能嗎?快速的谷歌搜索沒有顯示任何有用的信息。 –

3

你可以通過一些我稱之爲「手動AOP」的東西來達到這個目的。

先用AA方法定義一些基礎性狀捕獲包裹一個Option內的結果的概念,一個Future,或任何其他的容器中,一起進行實際的包裝:

import concurrent._ 

trait AbstractService { 
    type Result[T] 
    protected def result[T](code: => T) : Result[T] 
} 

然後專門此基特質爲FutureOption案件:

trait SyncService extends AbstractService { 
    type Result[T] = Option[T] 
    // Returns the original result wrapped in Some, 
    // or None if it was null or an exception occured 
    protected def result[T](code: => T) : Option[T] = { 
    try { 
     Option(code) 
    } catch{ case ex: Throwable => 
     ex.printStackTrace() 
     None 
    } 
    } 
} 

trait AsyncService extends AbstractService { 
    type Result[T] = Future[T] 
    protected val execContext: ExecutionContext 
    protected def result[T](code: => T) : Future[T] = { 
    future(code)(execContext) 
    } 
} 

現在你去好,可以這樣定義你的EntityGetService特點:

trait EntityGetService[ID, ENTITY] extends AbstractService { 
    def get(id: ID): Result[ENTITY] = result { 
    ??? 
    } 

    // add all the other method implementations here, taking care to 
    // wrap the method bodies inside "result" 
} 

// Now specializing EntityGetService as a sync or async service is just a matter 
// of mixing SyncService or AsyncService: 

class EntitySyncGetService[Long, Entity] extends EntityGetService[Long, Entity] with SyncService 
class EntityAsyncGetService[Long, Entity](implicit val execContext: ExecutionContext) extends EntityGetService[Long, Entity] with AsyncService 
+0

太棒了!你把我的思想包裹在裏面。 –

相關問題