[英]A good design pattern for implementing different behaviors on a subject
這種場景的最佳設計是什么?
我有不同的 Object 類型: User
、 Channel
、 MessageBox
、 UserGroup
等。
User
和Channel
可以擁有其他對象的權限。 例如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- 分別定義PermissionManager
、 UserPermissionManager
、 ChannelPermissionManager
類。 其他類只調用PermissionManager
,例如:
if (new PermissionManager.HasAccess(CurrentUser,
CurrentMessageBox,
UserPermissions.CanReadMessages))
然后PermissionManager
根據OwnerType
( UserPermissionManager
或ChannelPermissionManager
)決定與哪個 class 相關,並調用其HasAccess
方法。 這樣, PermissionManager.HasAccess
總是被調用,我認為它可以使代碼更易於維護和擴展。 這是我的首選解決方案,但由於PermissionManager
、 UserPermissionManager
和ChannelPermissionManager
引用相同的上下文,我認為應該有一個層次結構或可能是一個接口,以便這 3 個類變得更加集成。 但我不知道如何將它們聯系在一起。
2- 定義IPermissionManager
接口並從中實現UserPermissionManager
和ChannelPermissionManager
。 添加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.