依据对象反射信息生成业务规则的一种方法
2015-03-07林家伟胡俊生赖顺福
林家伟 胡俊生 赖顺福
摘要:在许多推理系统中,业务规则与代码紧耦合制约的系统应对业务变更的能力。因此,业务规则需要独立于系统。另一方面,系统在变更升级时,业务规则也要能快速地更改,需要有一定的依赖关系。独立关系与依赖关系构成了矛盾,该研究提出了一种依据对象的反射信息生成业务规则的方法。
关键词:推理;业务规则;反射
中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2015)35-0136-02
Abstract: In many of the reasoning system, business rules and codes are closely coupled with the ability of the system to cope with the business changes. Therefore, business rules need to be independent of the system. On the other hand, when the system changes, the business rules can be quickly changed, the need to have a certain dependence. This paper presents a method for generating business rules based on the object's reflection information..
Key words: reasoning; business rules; reflection
业务规则是业务在运行过程中的控制策略与方式。业务规则可以使用产生式[1]:IF P THEN Q的方式进行表示。在业务稳定的流程中,这种规则可直接写在代码中。但在实际环境中,业务的变更是频繁的。例如视频企业有:“在活动期所有观众可以任意点播本公司的免费视频”。此时前提P有三方面的限制,即时间=“活动期”、观众=“任意”、视频=“免费视频”,而结论Q则为点播。此时的主体为观众、客体对象及行为分别为视频、点播。然而这种业务规则是经常变化的,活动期不是一成不变的,而且观众类型、视频类型今后也有可能随商业活动的进行而动态调整。因此业务逻辑需要与系统分离。但另一方面,业务规则最终需要被系统所解析,并能用于流程的控制、数据访问等操作。因此业务规则又需要与系统存在一定的应对关系,存在一定的耦合。
这种分离与耦合构成了一对矛盾。本研究使用反射技术来解决这一问题。通过对系统已有对象的反射,得到各种类与其成员的详细信息,然后再根据这些信息生成业务规则。从而使得业务规则与系统存在紧密的应对关系。另一方面,这些业务规则又可以以XML格式存储于外部,便于动态修改。
1 假设前提
首先,应用程序中数据类的设计以ORM[2]思想为指导,类与其属性均与实际的实体一致。这种规范使得系统中类易于被规则的制订者所理解。这种方式也使得能通过反射技术从系统的EXE或DLL文件中读取系统所具有的类型,便于生成业务规则。
其次业务规则的表示以产生式方式表示。其中后件Q具体表示为TargetType.Method。其中TargetType是客体对象,而Method则为客体对象的方法。产生式的前件由简单条件或复合条件组成。简单条件可写为 <对象、运算符、比较值>的三元组。例如User.Age >= 18 。即User.Age表示对象,而>=为运算符,18为进行比较的值。而复杂条件,则由其他复杂条件、简单条件与Not、And、Or等关系组成而成。
在上述的复杂条件示例,是一个OR形式的条件,该条件又有两子条件,一为And复杂条件,另一个则为简单条件。代表的条件为“主体的年龄在18到30岁之间,或客体的类型为FREE”。
另外,对于简单条件又有一定的约束。简单条件的Object部分需要预留一部分关键字,如分别用Subject、Object代表主体、客体。此外,该关键字还需要能进一步扩展,用于代表其他事实,如系统配置等。对于有多层级的事实,采用“.”分割各层级。如用户类型下有角色Roles这一属性,而角色下又有权限Permissons属性,则可表示为Subject.Roles.Permissions。用RBAC形式表示“拥有管理员权限的用户可以删除视频”,则该规则可表示为:
考虑到实际情况,在生成业务规则时,还需要包含其他的信息,首先是DLL或EXE的版本信息,这些信息将用于验证后续的应用程序版本与业务规则版本是否一致。如果业务规则所需的类型来源于多个DLL或EXE,则这些文件版本均需要被记录。
采用反射技术[3]得到类型、属性等需要较大的性能开销。为了在对业务规则进行解析时提升性能。可以在记录业务规则的XML文件中保存这些类型的信息。
2 规则生成方法
2.1 类型的加载
类型的加载使用反射机制,通过查询程序集的元素据将程序集中的数据读出。本研究中将其读取后保存于XML文件上。其流程用以下的伪码表示:
1)获得所有程序集
2)对于每一个程序集,查找该程序集中所有的类型
3)对于每一个类型,只要不是基本数据类型,分别查找其各属性与行为,并生成XML节点
4)对于属性,如果不是基本数据类型,继续查找其各属性与行为,生成XML节点,并嵌入当前类型。
上述的3,4步骤是递归进行的,但是,这一流程会遇到无限循环的情况,例如教师类有对应的授课班级,而班级类则有对应的指导教师。此时教师与班级就存在相互引用的情况。由于类的成员之间相互引用情况复杂,这种链式的引用关系是很普遍的。因此在类型加载时要对这种情况进行处理。
因此可以结合动态规划与递归算法。首先建立一个类型表。将所有的类型(除去基本数据类型)保存于类型表中。当对某类型进行解析时,如果发现属性是一个未出现过的类型,则将当前属性的类型记录到类型表中。
2.2 规则的内存表示
规则在内存中以树型结点的方式表示,每一个规则均对应一棵二叉树。左子树为前提,而右子树为结论。而前提根据之前的假设,有Not、And、Or与Simple四种。
其中前提C={c|c∈Complex or c=Simple},即前提由一个复杂条件或一个简单条件构成。
而复杂条件则由运算符与其他条件(简单条件或复合条件)聚合而成。
如图1所示,业务规则Rule由两个成员Condition与Result组成,用于表示二叉树。而Condition则是一个抽象类,该类中有一个抽象方法,用于判断当前的事实环境下该条件的真假情况。由Condition派生出简单条件、And条件、Or条件、Not条件等子条件。Not条件中包含一个抽象的Condition,在运行时,可以用一个Not、And、Or及简单条件代替。而And、Or条件中则包含了Condition抽象类型的集合。最后的简单条件则由条件左部、操作符、比较值三个部分组成。
2.3 业务规则的生成
在图1中,Rule与Condition均使用了IToXML接口,因此均需实现ToXML的方法,该方法的出现将使得业务规则的生成分散到各个部分分批实现,减少了复杂度。
例如,对于简单条件,则需生成包含条件左部、操作符、比较值属性的XML节点即可。
在图2中,可以通过菜单加载程序集,并显示出所有的类型。这些类型与业务数据关联。通过双击相关属性以及生成器右侧的控件,可分别生成规则、复合条件及简单条件。最终可保存生成所需的业务规则。该规则独立于判断逻辑,也易于维护,也易于被系统解析。
3 结束语
在基于ORM的原则下,使用反射技术进行类及属性的获取,可获得独立于系统的业务规则。该规则易于生成与维护。由于规则中的类型与系统中的类名一致,也能易于被系统解析执行。但该系统还存在一些不足,如系统的类名习惯用英文方式表示,而用户习惯阅读中文,此时类型名与显示名还需要进行一定的转换。对于一些属性是集合类型是,可能需要执行筛选操作。以上这些也是后续改进的重点。
参考文献:
[1] 刘培奇, 李增智, 赵银亮, 等.扩展产生式规则知识表示方法[J]. 西安交通大学学报, 2004,38(6): 587-590.
[2] 吴卫平, 王丽芳, 蒋泽军, 等. 基于ORM的数据持久层框架研究[J]. 微电子学与计算机, 2008,25(7):188-190, 193.
[3] 朱有产, 李玉凯, 李自强, 等. 基于.NET反射技术的规约插件实现原理[J]. 继电器, 2006,34(22):60-63, 83.