2011-03-04 61 views
1

我有一個問題必須先回答幾次,但我無法找到任何好的搜索詞來找出解決問題的最佳方法。保存在數據庫中的不同用戶類型的工廠模式

在我的應用程序都會有不同類型的用戶,將有不同的屬性和不同的方法,但大部分也將是相同的。所以我創建了一個基類'用戶'和其他類'玩家','教練'等...繼承'用戶'類。

我應該如何把它保存在數據庫中,在一個名爲「用戶」有來自所有類的所有不同的屬性,還是應該我的數據庫看起來像我的班表巨大?我認爲解決方案2更好。

我只會有一個登錄方法,所以它會一直返回基類,但是當應該使用不同的特定類型('player','trainer')時,將會有一個類轉換到該類。但我怎麼做數據庫調用來填充我的不同類。

我可以做的是在用戶表中類型也保存。當我將這些信息返回給我的代碼時,我會檢查類型是什麼,然後調用數據庫獲取該類型的特定信息,創建正確的類型並將其作爲代碼中的「用戶」返回。但我不喜歡這樣的想法:我需要兩次調用數據庫來填充數據,我可以用SP解決它,但我儘量不使用SP。

有一個調用數據庫,當我不知道是什麼類型時,我打電話給數據庫將返回來解決這個的好辦法。

感謝您的任何幫助。

回答

1

首先,在我看來,我想建議你不要以爲基於它之上的面向對象的軟件解決方案關係的設計。

以最後一句爲真,我的暗示將每種類型的實體有什麼東西在企業做,你會設計一個數據表吧。

無論如何,我發現你可以有另一個關係設計。爲什麼不創建這樣的「用戶」表,其中包含基本信息,如唯一標識符,憑證以及用戶標識,身份驗證和授權所需的任何其他基本信息?

到這一點,你會設計的名爲「TrainerUsersProfiles」,「PlayerUsersProfiles」等關係表。

事實上,「TrainerUsersProfiles」,「PlayerUsersProfiles」有點像一個配置文件數據,因爲你是在爲了認證和授權應用程序的資源的用戶。但用戶可以擁有更多的相關信息,稱其爲「個人資料」。作爲培訓師或玩家的任何信息都是用戶個人資料的一部分。

現在是時候查看教練員和玩家(以及其他玩家)共享哪些屬性。這種共享屬性應該位於用戶的個人資料表「UsersProfiles」中,該表與用戶具有一對一的關係。

例如,我會在「TrainerUsersProfiles」和「PlayerUsersProfiles」中放置任何擴展配置文件數據,並且這兩個(或更多)將與某些用戶配置文件具有一對一的關係。

總結:用戶有一個配置文件,並且一個配置文件具有擴展的專用配置文件數據。

談到面向對象層 - 應用程序 - ,我想建議其最好避免抽象工廠和只使用一個存儲庫:

userRepository.GetById([id]) 

User類將有一個「類「屬性,這是一個用戶配置文件類型(培訓師,播放器等)的枚舉。

另外,User類還有一個「Profile」屬性,它本身也應該有一個「Properties」屬性。 「屬性」是一種類似於「ProfileProperties」的類型,並且有一個「TrainerProperties」和「PlayerProperties」派生它。

最後,這將是一些示例用法:

User someUser = userRepository.GetById([id]); 
string somePropertyValue = null; 

switch(someUser.Kind) 
{ 
    case Trainer: 
      somePropertyValue = ((TrainerProperties)someUser.Profile.Properties).SomeTrainerProperty; 
      break; 
    case Player: 
      somePropertyValue = ((PlayerProperties)someUser.Profile.Properties).SomePlayerProperty; 
      break; 
} 

我相信這可能是你正確的解決方案,它可以在一個良好的關係結束,面向對象的設計。

+0

這聽起來很有趣,它也解決了我遇到的另一個問題,即用戶可能既是玩家又是教練。通過添加配置文件列表,我可以解決這個問題,甚至可以讓用戶成爲玩家/培訓師/推薦人或以往任何人...... – 2011-03-04 18:32:47

+0

是的,這就是解決方案的要點。很高興知道它對您的解決方案有用! – 2011-03-05 14:04:50

1

這被稱爲「多態持久性」。有多種方法可以做到這一點。它們都有共同之處,就是在基表中有一列包含了每行中對象的真實類。

OR映射器使用此列來加載同一個表的更多列或加入其他表中的列。

查看Hibernate docs for more details。這是一個example from Java Tips