2011-04-12 207 views
4

讓我的應用程序包含業務類Order,Product,Customer等,我想在數據庫中存儲/檢索它們。斯卡拉DAO與類型分類

通常,我們使用DAO模式來達到此目的。也就是說,我們定義了一個DAO接口和實現爲每一個企業類:OrderDAOProductDAO等。現在我想用型類模式:

trait DAO[T] { 
    def create(t:T) 
    ... // other CRUD operations 
} 
... 
// DAO implementations for specific business objects 
implicit object OrderDAO extends DAO[Order] { 
    def create(o:Order) {...} 
    ... // other CRUD operations 
} 
... 
// create a business object in the database 
def create[T](t:T)(implicit dao:DAO[T]) {dao.create(t)}

現在我的問題是,所有DAOs使用DataSource實例(數據庫連接的工廠),因此我無法將DAOs定義爲objects。我應該創建一個DataSource的單例實例,並在初始化時將它傳遞給所有DAOs

比方說,我們有一個函數來創建一個DataSource

def dataSource():DataSource = {...}
你將如何實現 DAOs類型類

回答

1

同意薩莎。電梯的方式應該工作:

trait DataSource 

class MyDataSource extends DataSource 

object DataSources { 
    @volatile var dataSource:() => DataSource =() => new MyDataSource 
} 

有了這樣的方法,你可以使用object沒有鬆動的可測試性。

+0

有趣。你能解釋一下嗎? – Michael 2011-04-12 18:15:24

+0

對不起,代碼有誤。它必須是var,而不是def,我編輯它。 – tonek 2011-04-12 19:21:48

+0

使用這種方法,您實際上在DataSources變量中定義了變量,該變量包含數據源的函數工廠。在生產代碼中,您可以使用在對象DataSources中定義的變量的默認值。但在測試中,您可以重新定義該變量以返回您想要的任何內容。 – tonek 2011-04-12 19:29:12

2

我不認爲類型班是去這裏的路。類型類用於描述功能,而不是DI的替代品。

例如,如果您的DAO寫入鍵值存儲區,則可能需要將類轉換爲鍵和值的映射的功能。

在這種情況下,類型類:

trait KeyValuable[T] { 
    def toMap(t: T): Map[String, String] 
} 

你還可以用正確的實現提供每個業務類,無論環境的很明顯。它是這種類型的繼承能力,與你如何使用它無關。