2011-11-08 289 views
1

試圖遵守DRY原則,以下是使多個對象共享通用角色關係表的有效方法。共享相同角色關係表的多個實體

如果我們有以下幾種類型(純粹是爲了這個例子創建):

class User 
{ 
    ... 
} 

class Article 
{ 
    ... 
} 

這些對象都需要有對他們定義的角色。因此,角色對於這些對象中的任何一個都不是唯一的。

我的想法是讓Repositories在這些對象上執行CRUD操作,還讓Role有可能通過服務訪問它自己的Repository?

存儲庫會將UserDTO和ArticleDTO反饋給Builder類,該類將生成必需的Domain對象。在這種情況下:

class User 
{ 
    ... 
    IList<Role> Roles { get; set; } 
    //Other Domain objs/logic 
} 

class Article 
{ 
    ... 
    IList<Role> Roles { get; set; } 
    //Other Domain objs/logic 
} 

角色對象有一個角色表:

ID名稱

而且關係表:

的itemId角色ID ITEMTYPE

作用生成器/服務用於將角色附加到域對象可能看起來像這樣:

static class RoleBuilder 
{ 
    IEnumerable<Role> Fetch(int id, typeof(obj)) 
    { 
     //fetch from RoleRep 
    } 

    bool Save(IEnumerable<Role>, int id, typeof(obj)) 
    { 
     //save through role rep 
    } 
} 

這個想法有什麼內在的錯誤嗎?例如:

public static UserBuilder 
{ 
    public User FetchUser(int id) 
    { 
     //map userDTO to user 
     var user = map... 

     //populate roles 
     if(user != null) 
      user.Roles = RoleBuilder.Fetch(id, typeof(user)); 
    } 
} 

另一種方法是讓用戶和物品管理他們自己的角色操作並且可能有多個角色關係表例如user_has_roles,article_has_roles

第一種解決方案允許最終用戶也修改角色(重命名,添加新角色等),而不會破壞領域模型,而在第二種解決方案中,我不確定如何幹淨地做到這一點(更新他們通過用戶,通過文章?)

+0

貌似很多的精力來跟蹤「角色」,幾乎沒有任何與之相關聯的行爲。另外,從技術上講,說用戶和文章具有角色'IHaveRoles'或'HasRoles'(對於命名衝突如何)更合適。如果「角色」真的是一個單獨的概念,那麼可能值得探討它們是否屬於相同的有界環境。 –

+0

謝謝伊夫!我對我最初的建議的結構有了一些想法,並且已經改變了很多。我可能會發布更新以備將來參考。 –

回答

1

如果角色的概念是從用戶和文章分開 - 它聽起來像是因爲它適用於這兩個域對象 - 然後我可能會模型是分別像你建議。

我不確定當你說「允許角色被最終用戶修改」時你的意思。如果角色是一個單獨的概念,他們應該可以擁有自己的域類來表示可以針對角色執行的操作(重命名,刪除等)。

而且您的代碼段或許應該是這樣的(使用仿製藥,而不是無效的typeof()語法在上面的代碼中):

static class RoleBuilder { 
    static IEnumerable<Role> Fetch<T>(int id) { 
     switch(typeof(T)) { ... } 
    } 

    static bool Save<T>(IEnumerable<Role> roles, int id) { 
     switch(typeof(T)) { ... } 
    } 
} 

我可能也考慮有某種基類的所有可以分配角色的域對象(如果角色用於安全性,那麼可能是SecurableEntity或其他),那麼您可以在數據庫中擁有一個基類表以支持ID的共享標識(以便您可以擺脫itemType Roles表中的列)。或者,您可以使用GUID作爲實體ID,這使得許多事情變得更容易。

+0

Hi Dylan,「允許角色由最終用戶修改」,這意味着在UI中會有一個表單允許管理員(或指派的角色)更新系統中的角色。 –

0

你的想法聽起來不錯。我會避免將角色(或更一般的某種授權系統)與文章和用戶模型結合在一起。

我不喜歡你的代碼是什麼靜態RoleBuilder。首先:它是靜態的,會導致耦合。第二:RoleBuilder不應檢索從倉庫裏面卻得到薩姆例如通過例如一些服務推並從這個數據建立模型,角色或只是一個列表。如果讓RoleBuilder查詢Repo,可以將Builder的責任與查詢邏輯聯繫起來。

另一個問題可能來自你的UserBuilder實施出現。對於抓取單個用戶可能沒問題,但用該邏輯提取多個用​​戶將導致選擇N + 1。

0

您的倍數關係表的第二個想法是比較合適的。第一種方法將無法在數據庫中維護一個乾淨的外鍵。您應該能夠從任一實體更新角色,並且將反映在從另一個實體的存儲庫中獲取的下一個角色中。在我看來,通常最好是將參照完整性保留在數據庫中,並且將具有外鍵的表連接到角色表時,它將阻止您執行諸如將用戶實體附加到文章時從角色中刪除角色的操作實體。雖然第一種解決方案很聰明,但您必須實施一些業務邏輯以確保數據完整性......當ORM可以爲您做這件事情時,爲什麼這種事情會讓業務層混亂?

相關問題