【问题标题】:Designing an easily extensible library - can this design be improved?设计一个易于扩展的库——这个设计可以改进吗?
【发布时间】:2014-02-19 21:41:03
【问题描述】:

如果我正在考虑为我正在设计的库中的 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. 当我向角色添加新方法时,我希望具有该角色的 Personnel 对象能够“自动”执行新功能,而无需重新编译代码。

    李>

不管它的价值,这是我在许多项目中都需要的一个系统组件——一旦我有了正确的设计,我设想用以下语言(不同的项目)实现代码:Java、Python、Ruby(可能,PHP,C++),但是,我想首先正确地设计系统(连同上面提到的所需属性),而不必依赖于实现系统的语言提供的结构。

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

【问题讨论】:

    标签: design-patterns architecture rbac


    【解决方案1】:

    由于现在回复的不多,我只是给你一个抽象的答案。也许这也可以帮助其他人做出贡献。

    数据库

    “能力”表格包含

    主列:硬编码且永远无法更改的技能名称。

    “角色”表包含

    FK列:技能表PK作为外键

    主列:一些永远不会更改且永远不会重复每个角色的硬编码代码。

    **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 过滤并从“角色”表中选择正确的“能力”的存储过程并存储 他们在 ThousandClassParent.Abilities 中。 当您向该角色添加功能时 - 用户必须重新启动才能重新启动 OneOfAThousandClass 类 - 无需重新编译代码。

    所以有一个提示是否运行一个能力,这取决于用户角色,你们都有,那又如何? 界面没问题。我只会做的更少。所有一千个类都可以“使用”对辅助静态类的调用。 构造函数上的那个静态类可以获取能力表中的“能力”列表。

    当用户与角色类链接时,它会不时运行来自 ThousandClassParent 的肉函数,并传递一个代表访问能力的参数。

    所以函数 ThousandClassParent.Meat

    会是这样的
    if (DebugValidate(Ithinkthisabilityexists string))
    {
        if (Validate(Ithinkthisabilityexists string, ThousandClassParent.Abilities))
        PassesRunThis(Ithinkthisabilityexists string)
        else 
        FailsRunThis(Ithinkthisabilityexists string)
    }
    else
    {
    SystemError
    }
    

    DebugValidate 只是检查该功能是否真的存在于数据库中。除非您非常有信心,否则最好抓住这些错误。 如果传递的类角色能力数组包含该能力,则该静态类可以具有返回真或假的验证函数。 如果它通过,则调用不同的函数,如果不通过,则调用不同的函数,并将参数作为能力。有时,如果它没有通过,你会做更多的事情,而不是它通过时。 这两个函数将相似:它们将调用存储过程或文件名模板,并在与变量能力+后缀“失败”/“成功”同名的服务器上。您需要翻译模板 到真正的编程代码中的代码。我想尝试抽象它也太复杂了,而且它是一个比 RBAC 系统更普遍的主题,你可以将它作为一个单独的问题提出。

    【讨论】:

      猜你喜欢
      • 2021-12-20
      • 2023-03-28
      • 2011-02-14
      • 1970-01-01
      • 2016-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多