2010-10-07 78 views
2

在我的web應用程序中,授權用戶至少有4個「facets」:http會話相關數據,持久數據,facebook數據,運行時業務數據。斯卡拉特質/蛋糕模式vs案例分類

我已經決定與案件階級成分去特質,而不是至少有兩個方面的原因:

  • 性狀混合會導致名稱衝突
  • 我想免費的案例類的好東西像模式匹配和複製方法

我想知道有關此主題的經驗豐富的scalaists意見。它看起來像特質和/或蛋糕模式應該適合這樣的任務,但正如我上面提到的有問題......它顯而易見,不僅我想實現它快速和容易,但也深入瞭解它的使用在未來。

那麼我的決定是否存在任何缺陷和誤解或者是否正確? 相關的代碼如下所示:


case class FacebookUserInfo(name: String, friends: List[Long]) 
case class HttpUserInfo(sessionId: String, lastInteractionTime: Long, reconnect: Boolean) 
case class RuntimeQuizUserInfo(recentScore: Int) 
trait UserState { 
    def db: User 
    def http: HttpUserInfo 
} 

case class ConnectingUser(db: User, http: HttpUserInfo) extends UserState 
case class DisconnectedUser(db: User, http: HttpUserInfo, facebook: Option[FacebookUserInfo]) extends UserState 
case class AuthorizedUser(db: User, http: HttpUserInfo, facebook: FacebookUserInfo, 
          quiz: RuntimeQuizUserInfo) extends UserState

回答

1

第三個選項是使用隱式轉換器(又名「pimp my library」),這可能不是必需的,因爲您可以控制代碼。

這一切都取決於你想要如何不透明(或透明)你的對象的某些方面。你可以假裝它的一個普通的舊案例類到世界其他地方,但內部使它通過使用implicits做額外的工作。使用case類保存數據是合適的,但我也覺得使用三個類(ConnectingUserDisconnectedUserAuthenticatedUser)根據她的身份驗證狀態來表示同一個對象是很尷尬的。

object UserState { 
    def unapply(state: UserState) = Some(state.db, state.http) 
} 

這可以在匹配的狀態下使用,如下所示::

val user = ConnectingUser(User(), HttpUserInfo("foo", 0, false)) 
user match { 
    case UserState(db, http) => println(http) 
} 
+0

謝謝你的回答。我目前正在處理案例類(因爲修改使用特徵混合創建的obects也存在問題,我的意思是case類的複製方法的作用,因爲您必須使用反射或爲每個組合隱式定義構造方法的特點)。所以在我的情況下,隱式轉換以匹配特定的接口會很有用。 – 2010-10-10 14:07:13

3

我認爲答案很簡單:你同繼承,只要一切真的「屬於」你的對象,只要一切都在相同的「問題域」。

蛋糕模式的意圖是將某些需要但不真正包含它的對象的部分分解出來,例如,策略,裝飾,配置,上下文等。記錄將是一個典型的例子。一般來說,我們談論的是你不想「硬連線」的情況,例如您可能會考慮在Java中使用DI框架(如Guice或Spring)。請參閱http://jonasboner.com/2008/10/06/real-world-scala-dependency-injection-di.html就是一個很好的例子。

一個常常有助於決定做什麼的問題是:「我如何測試對象行爲?」。如果你發現建立一個合適的測試環境很困難,那麼很可能你應該去耦合一些東西,這就意味着DI,通常可以用蛋糕模式方便地實現。

+0

的「蛋糕圖案」

對於UserState,可以所以它的行爲等的情況下類提供的提取長期通常用於服務的背景下,而不是數據,我把它添加到我的問題,主要是因爲'名稱衝突'問題,這是各種特質混合共同的問題。 – 2010-10-07 07:46:52

+0

而且我還沒有完全理解'繼承'的含義。問題是什麼更好:特質混合(兩級模型)或組合。我不喜歡繼承(很多關卡模型),因爲它讓事情變得沉重。輕量級接口對我來說總是比較可取的,因爲它們使所有上下文更簡單(無需額外注意數據)。 – 2010-10-07 07:49:16