程序设计——规则
前言
程序员们在日常的工作中经常会面临分析需求、原型设计、程序设计、编码实现、测试及部署上线整个流程的其中一个或者多个环节。程序设计可以认为是最重要的环节之一,因为如果没有好的程序设计,所实现的功能必将在可复用性、扩展性、可维护性、可测试性等方面发生问题。本文着重讲解程序设计中最常见的一种思想——规则。
什么是规则?
根据百度百科的定义,规则是运行、运作规律所遵循的法则。以交通规则为例,交通规则是最常见的人类社会生活中的规则之一,它具有以下目的(引用百度百科的内容):
- 以保护交通参与人的合法权益为核心,突出保障,追求提高通行效率。从立法的指导思想、立法目的以及内容上都体现了本法的这一精髓:一是,坚持以人为本,预防和减少交通事故,保护交通参与人的合法权益;二是,提高通行效率,保障道路交通的有序、畅通。
- 坚持道路交通统一管理,明确政府及其相关部门在道路交通中的管理职责。明确提出政府应当保障道路工作与经济建设和社会发展相适应;同时又具体地规定政府应当制定道路交通安全管理规划,并组织实施。
- 将交通安全宣传教育上升为法律规定,明确规定政府以及公安机关交通管理部门,机关、部队、企事业单位、社会团体等单位,教育行政部门、学校,新闻、出版、广播、电视等媒体的交通安全教育义务。这符合我国道路交通事业发展的内在要求,符合现代交通管理工作的特点。
根据交通规则的目的,我们不难看出其具有严格、高效、统一、明确、具体等特点。如果这些交通规则交由程序去控制,是否也应当满足这些特点呢?答案是肯定的。
与交通规则不同的是,各大电商平台在双11大促期间各自推出自己的营销计划(比如:优惠券、红包、打折券、礼包等),这些营销计划具体来看都可以抽象为一个个营销规则(比如:满100元,送礼包)。由于笔者是java领域的开发人员,所以以java语言为基础介绍如何实现规则。
除了在人类生活中遇到的规则之外,很多数学定义、物理公式、化学公式、程序算法都可以认为是规则,下面我将以Tomcat、Spark及Drools为例介绍Web容器、大数据及规则引擎等方面,规则的不同实现。
规则引擎的工作机制
规则引擎的内部处理过程如图1所示,规则引擎从队列管理器中依次接收信息元,然后依规则的定义顺序检查信息元所带规则集中的规则。如图所示,规则引擎检查第一个规则并对其条件过滤器求值,如果值为假,所有与此规则相关的动作皆被忽略并继续执行下一条规则。如果第二条规则的过滤器值为真,所有与此规则相关的动作皆依定义顺序执行,执行完毕继续下一条规则。该信息元中的所有规则执行完毕后,信息元将被销毁,然后从队列管理器接收下一个信息元。在这个过程中并未考虑两个特殊动作:放弃动作(Discard Action)和包含动作(Include Action)。放弃动作如果被执行,将会跳过其所在信息元中接下来的所有规则,并销毁所在信息元,规则引擎继续接收队列管理器中的下一个信息元。包含动作其实就是动作中包含其它现存规则集的动作。包含动作如果被执行,规则引擎将暂停并进入被包含的规则集,执行完毕后,规则引擎还会返回原来暂停的地方继续执行。这一过程将递归进行。
图1 规则引擎
Tomcat中的规则
作为java程序员,想必都十分熟悉Tomcat吧,这也是笔者从事IT工作接触的第一个Web容器。在Tomcat的conf目录下的server.xml文件用于配置Tomcat内部的容器(如Server、Service等,具体内容可以参考《Tomcat源码分析——生命周期管理》一文的内容),由于server.xml只是一份XML格式的文件,所以需要由Tomcat将其转换为内部容器。以Server为例,Server元素的配置必须满足一定的规则,而且此规则是严格的,比如Server容器有port和shutdown两个属性,如果用户在Server元素上加一些莫须有的属性,Tomcat容器会在启动时会根据Server的配置按照规则生成相应实现类的实例(如StandardServer),给实例按照规则设置属性并对这些属性做严格的校验,以防止对Tomcat内部结构的破坏。Tomcat将这些生成规则(ObjectCreateRule)、设置属性规则(SetPropertiesRule)映射到不同的容器,保证了容器自身体系的健壮与稳定。server.xml的解析规则与规则引擎的工作机制非常类似,SetNextRule对应于规则引擎中的包含规则。图2展示了Tomcat中解析server.xml文件的规则,具体内容大家可以参考《TOMCAT源码分析——SERVER.XML文件的加载与解析》一文。
图2 server.xml解析过程
Spark SQL中的规则
Spark是一个通用的并行计算框架,由加州伯克利大学(UCBerkeley)的AMP实验室开发于2009年,并于2010年开源。目前已是大数据领域最活跃的开源项目之一,为了降低使用的门槛,Spark团队已经增加了SQL查询的能力。Spark SQL与Mysql、Oracle、Microsoft SQL server类似,在执行查询语句的时候,都会将查询语句转换为一棵语法树,如图3(图片来自网络)所示。
图3 SQL解析为语法树示例
在Spark中是使用SqlParser这一组件完成SQL的解析和语法树的生成的,然后利用分析器Analyzer结合数据字典(Catalog)对语法树进行绑定操作,最后还会使用优化器Optimizer对语法树进行优化(类似于关系型数据库中执行计划的选择),这些的逻辑执行计划在最终转化为物理执行计划后才会执行。
无论是Analyzer还是Optimizer,其分析与优化都可以认为是一组规则,通过将这些规则应用到语法树上,完成对逻辑执行计划的分析与优化工作,整个过程如图4(图片源自csdn)所示。
图4 Spark SQL绑定与优化过程
与Tomcat中的规则是与具体容器对象绑定的不同,无论什么SQL在转换为语法树后,通过对树的遍历操作,由分析器和优化器应用自身的规则。
Java规则引擎
JSR94 Rule Engine API中定义了Java规则引擎所必须的接口定义。Java规则引擎的工作机制与规则引擎的工作机制十分类似,只不过对规则引擎重新进行了包装与组合。Java规则引擎对提交给引擎的Java数据对象进行检索,根据这些对象的当前属性值和它们之间的关系,从加载到引擎的规则集中发现符合条件的规则,创建这些规则的执行实例。这些实例将在引擎接到执行指令时、依照某种优先序依次执行。一般来讲,Java规则引擎内部由下面几个部分构成:工作内存(Working Memory)即工作区,用于存放被引擎引用的数据对象集合;规则执行队列,用于存放被激活的规则执行实例;静态规则区,用于存放所有被加载的业务规则,这些规则将按照某种数据结构组织,当工作区中的数据发生改变后,引擎需要迅速根据工作区中的对象现状,调整规则执行队列中的规则执行实例。Java规则引擎的结构示意图如图5所示。
图5 Java规则引擎工作机制
目前开源的Java工作引擎如下:
JBoss Drools
Drools是Jboss公司旗下一款开源的规则引擎,它完整的实现了Rete算法;提供了强大的EclipsePlugin开发支持;通过使用其中的DSL(DomainSpecificLanguage),可以实现用自然语言方式来描述业务规则,使得业务分析人员也可以看懂业务规则代码。最新版本Drools5提供了基于WEB的BRMS——Guvnor,Guvnor提供了规则管理的知识库,通过它可以实现规则的版本控制,及规则的在线修改与编译,使得开发人员和系统管理人员可以在线管理业务规则。
Easy Rules
Easy Rules是开源的轻量级的Java规则引擎,其实现基于基于POJO/注解并提供了强大的功能。
Mandarax
Mandarax是一个规则引擎的纯Java实现。它支持多类型的事实和基于反映的规则,数据库,EJB等等,支持XML标准(RuleML 0.8)。它提供了一个兼容J2EE的使用反向链接的接口引擎。
Apache Camel
Apache Camel是Apache基金会下的一个开源项目,它是一个基于规则路由和处理的引擎,提供企业集成模式的Java对象的实现,通过应用程序接口 或称为陈述式的Java领域特定语言(DSL)来配置路由和处理的规则。
JLisa
JLisa是一个利用java构建商业规则的强大框架。它实现了JSR94 Rule Engine API。
OpenRules
OpenRules基于java完全开放源代码的商业规则管理框架。它有效的利用了MS Excel,Eclipse IDE 和其它java开源类库去构造,维护,部署,执行不同的复杂商业逻辑的规则引擎。
JEOPS
JEOPS(The Java Embedded Object Production System)是一个基于Java的演绎法(Forward-Chaining)规则引擎。这个规则引擎被用于在Java 应用服务器,Java客户端程序,和Servlets中通过规则来提高它们的商业处理能力。
InfoSapient
InfoSapient是一个开源的规则引擎。它设计用来表达,执行和维护在同一个公司中商业规则。InfoSapient基于纯Java开发,使用了MVC,Visitor,Strategy,Facade,Factory Method,Observer,Iterator等设计模式。
JRuleEngine
JRuleEngine基于JSR94规范的java规则引擎。
Roolie
Roolie是一个极其简单的Java规则引擎(Non-JSR94)它使用你在Java中创建的规则。 简单创建基本的规则,为每个规则实现单个"passes"方法,然后在一个XML文件中将它们链起来创建更复杂的规则。
总结
通过对一些开源系统的整理和分析,总结出一些可以应用于日常业务开发中的共同点。如果你的业务与市场推广、营销、广告等业务有关,这些都是应用规则引擎的地方。我们也可以通过对业务抽象,将规则应用到更多业务系统中。
注意:本文部分内容引用自网络,包括百度百科及CSDN。
如需转载,请标明本文作者及出处——作者:jiaan.gja,本文原创首发:博客园,原文链接:http://www.cnblogs.com/jiaan-geng/p/4939293.html