【发布时间】:2011-04-18 09:24:38
【问题描述】:
我正在启动一个 Web 应用程序,客户端用纯 ExtJS 实现,中间层用 Grails 实现。该应用程序具有基于角色的授权,其中用户可以拥有许多细粒度的角色,如 SOME_FORM_READ、SOME_FORM_UPDATE、SOME_DATA_DELETE、SOME_DATA_READ 等。根据用户的角色,需要禁用或隐藏某些 GUI 元素,而其他需要处于只读模式。
我在网上做了一些搜索,但没有找到任何专门解决这个问题的设计模式,所以我想出了自己的设计。我相信很多网络应用程序都会有类似的要求,所以我想在这里发布我的设计并听取人们的意见。我的设计绝不是完美的,但我希望它可以随着大家的投入而改进。虽然我正在使用 ExtJS,但总体设计也应该适用于类似的框架,如 GWT、Flex、Swing 等。
那么,就这样吧:
关于授权,我们需要在客户端层处理四种类型的代码(或信息):
-
GUI元素操作代码,例如:
panel.hide() form.setReadOnly(true)
-
GUI元素权限要求,例如:
form.requires('READ', 'FORM_READ_ROLE')
adminPanel.requires('ADMIN_ROLE')
用户权限信息,基本上是用户拥有的角色列表;
授权逻辑:根据用户权限确定隐藏/禁用哪些元素;
设计的核心是一个单例,命名为GUIPermissionManager,简称GPM。这是一种集中式设计,因为大部分代码都在 GPM 中,因此 GUI 元素不会被授权代码污染。这就是 GPM 的工作原理:
-
GUI 元素(需要特定权限才能访问)向 GPM 注册其权限信息,如下所示:
GPM.register(this, 'DEPARTMENT_DELETE_ROLE'); // 删除部门按钮
GPM 维护一个 GUI 权限注册列表
在用户登录时,GPM 接收分配给用户的角色列表
GPM 遍历 GUI 权限注册列表并根据用户权限确定要隐藏 GUI 的哪个部分,然后相应地调用 element.hide()
问题:
- GUI 元素按树形层次结构组织,例如一个面板包含一个按钮栏和一个表单,所以当面板被隐藏时,不需要进一步检查按钮栏和表单是否需要隐藏。 问题:如何在 GPM 中注册和维护这些分层信息?
- 目前,我只能想到 GUI 元素的两个用例:隐藏元素或将元素设置为只读(例如表单)。还有其他用例吗?
- 在ExtJS中,隐藏一个元素,我们调用hide(),但是设置一个表单只读,我们必须想出我们自己的函数,比如说它叫做setReadOnly(),如何让GPM知道哪个调用函数?将函数作为注册的一部分传递?
- 将表单设置为只读的最佳方法是什么?如果我使用 setReadOnly() 功能扩展表单组件,将会有很多代码重复,我必须为每个需要权限控制的表单执行此操作。是否可以在 GPM 中创建动态表单转换器,以便在表单设置为只读时自动将所有可编辑字段替换为仅显示字段?
【问题讨论】:
-
您不应该打开一个“问题”并提出 10 个问题。创建多个问题,每个问题都详细说明您要完成的工作,或者只打开一个提出更一般/概念/架构问题的问题.
-
最后一个问题可能是独立的。但如果脱离讨论上下文,其他 3 个将没有多大意义。
标签: design-patterns gwt user-interface extjs