簡體   English   中英

用於在主題上實現不同行為的良好設計模式

[英]A good design pattern for implementing different behaviors on a subject

這種場景的最佳設計是什么?
我有不同的 Object 類型: UserChannelMessageBoxUserGroup等。
UserChannel可以擁有其他對象的權限。 例如User將以下枚舉定義為MessageBox的權限:

CanRead,
CanWrite,
CanDelete,
...

其他枚舉為User定義為其他 object 類型的所有者。

此外, Channel在這些對象上具有不同的枚舉值。 例如,將Channel視為所有者,將MessageBox視為 object:

CanDispath
CanRetrieve
...

使用按位比較從數據庫中的特定表中保存和檢索所有權限:

OwnerID........OwnerType........ObjectID........ObjectType........AccessLevel  
  1              User              10           MessageBox            38     
  5             Channel            12           MessageBox            18  

現在在后面的代碼中,實現權限類的最佳方法是什么?

1- 分別定義PermissionManagerUserPermissionManagerChannelPermissionManager類。 其他類只調用PermissionManager ,例如:

if (new PermissionManager.HasAccess(CurrentUser,  
                                    CurrentMessageBox, 
                                    UserPermissions.CanReadMessages))  

然后PermissionManager根據OwnerTypeUserPermissionManagerChannelPermissionManager )決定與哪個 class 相關,並調用其HasAccess方法。 這樣, PermissionManager.HasAccess總是被調用,我認為它可以使代碼更易於維護和擴展。 這是我的首選解決方案,但由於PermissionManagerUserPermissionManagerChannelPermissionManager引用相同的上下文,我認為應該有一個層次結構或可能是一個接口,以便這 3 個類變得更加集成。 但我不知道如何將它們聯系在一起。

2- 定義IPermissionManager接口並從中實現UserPermissionManagerChannelPermissionManager 添加PermissionManagerTypes枚舉。 創建工廠 class 並呼叫經理,例如:

IPermissionManager UserManager =   
    PermissionFactory.Create(PermissionsManagerTypes.User);
if (UserManager.HasAccess(CurrentUser,  
                          CurrentMessageBox, 
                          UserPermissions.CanReadMessages))  

這是一種將類關聯在一起的失敗嘗試。 但我認為最好在這里提及它,讓您知道我想要實現的目標。

PS 我無法將類定義為 static,因為它們需要具有ObjectContext (實體框架)類型的私有變量。

有沒有更好的解決方案來實現這一目標?
謝謝你,很抱歉這個很長的問題。

嗯,這很難回答。 您可以嘗試創建一個基本接口 IPermission;

interface IPermission<TOwner>
{
}

然后為您希望能夠擁有權限的類型實現此接口。

class UserPermission : IPermission<User>
{
    public UserPermission(CustomerPermissionType type)
    {
        // Store the type
    }
}

class ChannelPermission : IPermission<Channel>
{
    public ChannelPermission (ChannelPermissionType type)
    {
        // Store the type
    }
}

現在您需要一個為特定對象提供權限的接口。

interface IPermissionProvider
{
    bool HasPermission<TOwner>(IPermission<TOwner> permission, TOwner owner, object target);
}

此時您已具備查詢權限的基本功能。 問題是如何管理用戶和頻道權限的不同處理。 你可以實現這樣的事情:

class PermissionDispatcher : IPermissionProvider
{
    public void RegisterPermissionProvider<TOwner>(IPermissionProvider     permissionProvider)
    {
        // Store it somewhere
    }

    public IPermissionProvider GetPermissionProvider<TOwner>()
    {
        // Look up a permission provider that is registered for the specified type TOwner and return it.
    }

    bool IPermissionProvider.HasPermission<TOwner>(IPermission<TOwner> permission,     TOwner owner, object target)
    {
        IPermissionProvider  permissionProvider = GetPermissionProvider<TOwner>();
        return permissionProvider .HasPermission<TOwner>(permission, owner, target);
    }
}

最后一步是為 User 和 Channel 創建 IPermissionProvider 的特定實現,並在應用程序/服務啟動時將它們注冊到 PermissionDispatcher。

用法就像這樣簡單:

void foo()
{
    IPermissionProvider permissionProvider = ... the dispatcher, could be a singleton ...;
    User user = ...;
    MessageBox messageBox = ...;
    UserPermission userCanReadPermission = new UserPermission(UserPermissionType.CanRead);
    bool hasUserCanReadPermission = permissionProvider.HasPermission(userCanReadPermission, user, messageBox);

}

這樣的事情將是解決此問題的唯一方法,而不依賴於您的域類型中的權限處理。 盡管如此,我絕對確定這不是完美的解決方案。

我根本沒有考慮這一點,但是:

interface HasPermissions {
   getPermissionsFor(object)
}

User implements HasPermissions

Channel implements HasPermissions

etc..


User user = new User();

if user.getPermissionsFor(object).contains(canRead)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM