2011-04-15 130 views
6

讓我們看看幾個單獨的DAO類OrderDAO,ProductDAOCustomerDAO,它們在數據庫中存儲/檢索數據並共享單個實例DataSource(數據庫連接工廠)。關於蛋糕模式的問題

爲了創建DataSource實例並將其插入DAOs,我們通常使用Spring DI。現在我想在沒有任何DI框架的Scala中這樣做。

我讀過有關cake pattern,它看起來像我應該做到以下幾點:

trait DatabaseContext { val dataSource:Datasource } 

trait OrderDAO {this:DatabaseContext => 
    ... // use dataSource of DatabaseContext 
} 

trait ProductDAO {this:DatabaseContext => 
    ... // use dataSource of DatabaseContext 
} 

object DAOImpl extends OrderDAO with ProductDAO with DatabaseContext { 
    val dataSource = ... // init the data source 
} 

我是否正確理解了蛋糕的圖案?

我可以使用蛋糕圖案以不同方式實施這些DAOs嗎?

它提供了像Spring這樣的DI框架嗎?

如何創建單獨的OrderDAOImplProductDAOImpl對象共享相同DataSource實例而不是一個大DAOImpl

+0

我簡要閱讀了關於蛋糕模式,並沒有看到興奮是關於什麼。看起來比現有的DI容器複雜得多。 – Kevin 2011-04-15 17:06:48

回答

2

可能:

  • 在編譯時靜態檢查。
5

濾餅圖案的優點是:

  • 不像基於配置文件DI解決方案,匹配合同 實現是在編譯時,這減少了 和兼容性類調查問題完成的。但是,許多DI引擎具有 替代代碼內配置功能
  • 沒有使用第三方庫 。允許您使用該模式的自我類型註釋是 本地語言功能。沒有特殊的語法來檢索 執行合同
  • 忘記指定一個 實現在 由另一個組件結果需要一個運行時錯誤的組件 - 只是檢查本文 http://jonasboner.com/2008/10/06/real-world-scala-dependency-injection-di.html ,儘量不指定的一個組件或指定 特質,而不是一個具體的類中的任何蛋糕圖案的 例子,甚至忘了初始化對應

但是需要一個部件的VAL,體驗到這些優勢,就需要更加嚴格地遵守到模式的體系結構 - 查看相同的文章,並注意包含實際合同和實現的包裝特徵。

你的例子似乎不是嚴格的蛋糕模式。在你的情況下,你可以使用繼承爲你的特性創建實現,併爲每個DAO組件使用單獨的類。在cake模式中,使用代碼就像DAO代碼一樣是一個組件,組裝依賴關係的代碼將獨立於它。

爲了說明蛋糕模式,您必須在您的示例中添加使用類(域層或UI層)。或者你的DAO組件訪問對方的功能,你可以單獨說明你的DAO的蛋糕模式。

,使之短,

trait OrderDAOComponent { 
    val dao: OrderDAO 
    trait OrderDAO { 
     def create: Order 
     def delete(id: Int): Unit 
     //etc 
    } 
} 

trait OrderDAOComponentImpl extends OrderDAOComponent { 
    class OrderDAOJDBCImpl extends OrderDAO { 
     def create: Order = {/*JDBC-related code here*/} 
     def delete(id: Int) {/*JDBC-related code here*/} 
     //etc 
    } 
} 

//This one has a dependency 
trait OrderWebUIComponentImpl { 
    this: OrderDAOComponent => 
    class OrderWebUI { 
     def ajaxDelete(request:HttpRequest) = { 
      val id = request.params("id").toInt 
      try { 
       dao.delete(id) 
       200 
      } 
      catch { 
       case _ => 500 
      } 

     } 
    } 
} 

//This matches contracts to implementations 

object ComponentRegistry extends 
    OrderDAOComponentImpl with 
    OrderWebUIComponentImpl 
{ 
    val dao = new OrderDAOJDBCImpl 
    val ui = new OrderWebUI 
} 

//from some front-end code 
val status = ComponentRegistry.ui.ajaxDelete(request) 

更多關於你的榜樣。我認爲它可能更像蛋糕,如果:

trait DatabaseContext { val dataSource:Datasource } 

trait OrderDAOComponent {this:DatabaseContext => 
    trait OrderDAOImpl { 
     ... // use dataSource of DatabaseContext 
    } 
} 

trait ProductDAOComponent {this:DatabaseContext => 
    trait ProductDAOImpl { 
     ... // use dataSource of DatabaseContext 
    } 
} 

object Registry extends OrderDAOComponent with ProductDAOComponent with DatabaseContextImpl { 
    val dataSource = new DatasourceImpl //if Datasource is a custom trait, otherwise wrapping needed 
    val orderDAO = new OrderDAOImpl 
    val productDAO = new ProductDAOImpl 
} 

//now you may use them separately 
Registry.orderDAO.//