我希望得到一些关于设计的反馈,我正在考虑为我正在设计的库中的RBAC子系统实现。下表提供了类名和简要说明:
Name Description
User Abstract Base Class (so it can't be instantiated)
IRole Interface
Role Implements IRole
RoleCollection Collection of roles
Personnel ABC. Represents a user in the system. Derives from User, delegates to (i.e. has-a) collection of roles (RoleCollection)
PersonnelFactory Creates specific personnel types
由 PersonnelFactory 创建的人员的一些示例:
SystemAdminPersonnel
AccountsPersonnel
... etc
我想将角色分区为离散类,其中专用的自定义角色类(实现IRole接口)执行特定的功能。也就是说,例如:
SystemAdminRole 可以使用以下方法:
clearSystemCache();
createNewCache();
... etc.
虽然 AccountsRole 可以使用以下方法:
updateUserAccount();
getAccountBalance();
addAmountToAccountBalance();
... etc
理想情况下,我希望系统显示以下属性:
能够为角色添加新功能,而无需修改代码。我打算通过使用(a)脚本(b)可调用存储过程
当我向角色添加新方法时,我希望具有该角色的Personnel对象能够“自动”执行新功能,而无需重新编译代码。
为了它的价值,这是我在许多项目中需要的系统组件 - 一旦我有正确的设计,我设想用以下语言(不同的项目)实现代码:Java,Python,Ruby(可能但是,我希望首先使系统设计正确(连同上面提到的所需属性),而不必依赖系统实现的语言提供的结构。
非常感谢有关如何改进或修改上述设计以获得所需功能(无需重新编码的可扩展性)的任何建议。
答案 0 :(得分:0)
由于现在没有很多回复,我只是给你一个抽象的回答。也许这可以帮助其他人做出贡献。
<强>数据库强>
“能力”包含
的表格列主要:硬编码的能力名称,永远不能更改。
“角色”包含
的表格列FK:能力表PK为Foriegn Key
Column Main:一些永远不会改变并且永远不会复制每个角色的硬编码代码。
<强>类强>
**ThousandClassParent** Class
-Array Abilities
-Constant Variable RoleName
-Meat(Ithinkthisabilityexists string)
**OneOfAThousandClass** Class Inherits *ThousandClassParent*
-Constructor()
**Helper** Static Class
-Array Abilities
-Constructor
-DebugValidate(Ithinkthisabilityexists string)
-Validate(Ithinkthisabilityexists string, ThousandClassParent.Abilities)
-PassesRunThis(Ithinkthisabilityexists string)
-FailsRunThis(Ithinkthisabilityexists string)
在每千个类中,每个类代表一个角色(OneOfAthousand类),它们的父级将是ThousandClassParent类。 在OneOfAThousand类的构造函数上,ThousandClassParent.RoleName存储表Roles.Main(除非角色已过时,否则不会再次更改此数据或在数据库中更改) 之后,调用使用ThousandClassParent.RoleName的存储过程来过滤并从“roles”表和存储中选择正确的“能力” 他们在ThousandClassParent.Abilities。 当您向该角色添加功能时 - 用户必须重新启动以选择重新启动类OneOfAThousandClass - 无需重新编译代码。
所以有一个提示是否运行一个能力,它取决于用户角色,你们都拥有它们,那么呢? 界面还可以。我会少做。所有上千个类都可以“使用”对辅助静态类的调用。 构造函数上的静态类可以获取能力表中的“能力”列表。
当用户与角色类链接时,它将不时运行来自ThousandClassParent的meat函数并传递一个表示访问权限的参数。
对于函数 ThousandClassParent.Meat
,它会是这样的if (DebugValidate(Ithinkthisabilityexists string))
{
if (Validate(Ithinkthisabilityexists string, ThousandClassParent.Abilities))
PassesRunThis(Ithinkthisabilityexists string)
else
FailsRunThis(Ithinkthisabilityexists string)
}
else
{
SystemError
}
DebugValidate只是检查数据库中是否确实存在该功能。除非你非常自信,否则抓住这些错误是件好事。 如果传递的类角色能力数组包含该能力,那么该静态类可以具有返回true或false的验证函数。 如果它通过则调用另一个函数,如果它没有以参数作为能力传递,则调用另一个函数。有时你会做更多的东西,如果它没有通过,而不是通过。 这两个函数类似:它们将调用存储过程或文件名模板,并在服务器上调用与变量ability + post-prefix“fail”/“success”相同的名称。您需要翻译模板 到代码中真正的编程代码。我想试图抽象一下也太复杂了,它比RBAC系统更普遍,你可以把它作为一个单独的问题。