设计一个易于扩展的库 - 可以改进这种设计吗?

时间:2014-02-19 21:41:03

标签: design-patterns architecture rbac

我希望得到一些关于设计的反馈,我正在考虑为我正在设计的库中的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

理想情况下,我希望系统显示以下属性:

  1. 能够为角色添加新功能,而无需修改代码。我打算通过使用(a)脚本(b)可调用存储过程

  2. 来实现这一点
  3. 当我向角色添加新方法时,我希望具有该角色的Personnel对象能够“自动”执行新功能,而无需重新编译代码。

  4. 为了它的价值,这是我在许多项目中需要的系统组件 - 一旦我有正确的设计,我设想用以下语言(不同的项目)实现代码:Java,Python,Ruby(可能但是,我希望首先使系统设计正确(连同上面提到的所需属性),而不必依赖系统实现的语言提供的结构。

    非常感谢有关如何改进或修改上述设计以获得所需功能(无需重新编码的可扩展性)的任何建议。

1 个答案:

答案 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系统更普遍,你可以把它作为一个单独的问题。