可配置权限的图形用户界面框架的分析(1)
来源:互联网 发布:pl sql developer 64位 编辑:程序博客网 时间:2024/06/10 21:02
1. 前言
作为一个图形用户界面开发人员,都会被繁复的界面呈现权限逻辑困扰过,多年来,界面开发的编写方式都没有太大的改变,界面程序中总是掺杂着许多条件判断语句,本文的目的就是对这种问题的分析和解决。
希望对这种类型的GUI框架有研究的网友能发表自己的看法,多多交流。
2. 切入点
本文的切入点在于根据不同的条件判断语句显示控件,这是界面逻辑的主体。
3. 阅读要求
需要阅读者基于GUI框架写过程序,诸如MFC, VCL, wxWidgets,或者struts, webwork之类,其他语言的GUI框架也行。
本文中的术语界面元素,在一般的书籍中称为窗口组件,但是最近流行的SWT、GWT等都喜欢用Widget做类名,中文翻译和组件没什么关联,因此换个名称。
4. 第一阶段--现状
仍然用我的老朋友--请假单作为案例,以下人名纯属虚构,如有巧合,纯属偶然。一张请假单在普通员工填写时,请假原因一栏是可读写的。
但是当部门经理和其他角色阅读时,为只读状态。
如果是用编程语言实现权限判断,那么伪码为
if (普通员工角色.包含(当前用户)) { (new TextArea("请假原因")).draw(); } else if (经理角色.包含(当前用户)) { (new Text("请假原因")).draw(); } |
如果是struts,那么标签伪码为
<c:if test="普通员工.包含(当前用户)"> <html:textarea id="请假原因"/> </c:if> <c:if test="经理角色.包含(当前用户)"> <html:text id="请假原因"/> </c:if> |
通过上面的例子,我们看到为了在两种角色下分别呈现请假原因控件,写了两段,可以联想到如果有更多的角色要查看同一个页面时会发生什么事--更多的权限判断代码+更多的同id控件输出,就算封装得再漂亮,但只要不改变这种写代码的本质,情况就不会改变。这种同一个id的控件写上多次的情况,是造成编码量急剧增加且难以维护的主要原因。
5. 第二阶段--分析和实现
要实现权限可配置,除非权限也是对象,那么干脆就假设权限是对象,定义相关规则如下。
l 将权限作为独立对象。
那么将上面的代码用对象模型用来表达,如下
同时也要解决同名id控件的重复性问题,则假设控件可以根据权限自动决定如何呈现界面,相同id的控件实际只为1个。那么对象模型就变成下面的图
很容易看出,现在的我们只是要对权限和控件两坨对象之间进行逻辑关联,以确定如何呈现界面。
再定义出如下几条规则,以方便编写代码:
l 控件使用权限对象引用来和权限对象绑定。
l 将权限引用包含到控件内。
现在,伪码变成这样
<ScriptRight id="普通员工权限" script="普通员工角色.包含(当前用户)"/> <ScriptRight id="经理权限" script="经理角色.包含(当前用户)"/> <Textarea id="请假原因"> <RightRef id="普通员工权限" value="读写"/> <RightRef id="经理权限" value="只读"/> </Textarea> |
似曾相识吧?没错,类似Ant里Path和PathRef标签的写法。
现在代码完全的对象化了,结构清晰。控件越多这种写法的优势越明显。...
当然,上面的规则不是很完整,为了能够实现控件自决定呈现,得加上几条:
l 权限值有 读写、只读、隐藏、禁止 四种。
l 权限值为读写时调用控件的界面呈现方法。
l 权限值不为读写时由控件在内部决定类型转换,然后调用转换后对象的呈现方法--默认情况下只读转换为文本,隐藏转换为hidden标签,禁止则删除该对象。
这样的规则复杂度一般,要想实现把呈现的变换隐藏到控件内部,则将权限值当作独特的状态值来看待,使用《设计模式》中的状态模式就可以了。
到目前为止,离实用还有点距离,灵活性还不够,因为在权限改变时,控件的属性会改变,比如,对于提交按钮来说,提交时的javascript处理函数会改变,假设需求如下:
在其他权限时,生成html代码 <input type='submit' id='提交' value='提交' onclick='doA()'/> 但在经理权限时,要生成 <input type='submit' id='提交' value='提交' onclick='doB()'/> |
因此再订一条规则来包容属性变化:
l 允许在权限匹配时,修改控件的属性。
假设我们有如下需求
下面是示例代码
<ScriptRight id="普通员工权限" script="普通员工角色.包含(当前用户)"/> <ScriptRight id="经理权限" script="经理角色.包含(当前用户)"/> <SubmitButton id="提交"> <HTMLAttributes onclick="funcA()" style="color:blue"/> <RightRef id="普通员工权限" value="读写"/> <RightRef id="经理权限" value="读写"> <field name="HTMLAttributes.onclick" value="doB()"/> </RightRef> </SubmitButton > |
现在对上面的代码说明。
HTMLAttributes是SubmitButton标签对应的处理类SubmitButton的属性,类图如下
大部分开源框架配置文件xml元素对应的处理类都是这么写的,规则为:
l 同名的标签对应同名的类。
l 同名的属性对应同名的参数或者子标签。
在这里,HTMLAttributes子标签里的所有参数,将原封不动的生成为HTML字符串(也可以考虑支持EL表达式),在权限引用(RightRef)标签里,子标签field表示,符合本权限时,将
name参数值对应的控件对象的属性值按照反射规则重写。用java伪码表达就是
/* 本例中 * fieldName = "HTMLAttributes.field"; * fieldValue = "doB()"; */ public void setField(Object control, String fieldName, Object fieldValue) { if (fieldName.contains(".")) { String[] fieldNames = fieldName.split("."); Object field = BeanUtil.getProperty(control, fieldNames[0]); if (field.getType() == Map) { ((Map)field).put(fieldNames[1], fieldValue); } } } |
虽然可实现本例的功能,但可以看出这段伪码是有缺陷的,完整的反射设置代码会复杂得多。
至此,我们拥有了完全对象化而且可配置的模型,这个模型完全可以不用在界面程序(这里用jsp,但可以是其他语言的界面程序文件)中硬编码权限,可以考虑两种整体解决方案:
l 方案1:仍然在Jsp中写控件代码(这样原有标签可以不改,改后台实现即可),然后把权限标签和权限引用标签独立到另一个xml文件(此时权限引用标签作为权限标签的子标签或者独立标签均可)。
l 方案2:把控件、权限、权限引用全部放到一个xml中进行,jsp退化为模板,好处是可以实现整体式GUI框架,需要跨平台GUI库的话很合适。
2008-11-09
第二篇文章完成。
- 可配置权限的图形用户界面框架的分析(1)
- 可配置权限的图形用户界面框架的分析(2)
- 简单的图形用户界面
- R语言的图形用户界面
- FANN的图形用户界面形式
- 五:Windows的图形用户界面
- 图形用户界面的初步认识
- 图形用户界面集合框架
- MATLAB图形用户界面的一个实例(1)
- 我选择 wxWidgets 而不是 Qt 作为图形用户界面框架的一些想法
- 用Swing编写灵敏的图形用户界面
- 用Swing编写灵敏的图形用户界面
- SWT图形用户界面的几个小技巧
- WinCE.net下图形用户界面的开发
- 嵌入式Linux系统的图形用户界面
- 嵌入式系统的图形用户界面设计研究
- 一些实用的图形用户界面方法
- 简单的图形用户界面猜数字
- 神奇!一张图测试你是用左脑还是右脑! (含控制方法揭秘)
- 转帖收藏下载
- 配置Linux逻辑卷管理器(LVM)
- 开始学习java
- 虚拟shell终端程序
- 可配置权限的图形用户界面框架的分析(1)
- 相交圆误差问题
- ubuntu安装/卸载软件的基本命令
- Windows WIM文件的分割,合并,瘦身操作
- TCP AIMD Algorithm (copy)
- 系统程序员成长计划-谁动了你的隐私(下)
- 从今天开始入住CSDN博客了
- 美国:一半员工不敬重自己的老板
- 晨会纪要081103