javs引擎

人气:11073
访问用户量:17
笔记经验:25
总积分:175
级别:普通会员
搜索本笔记
ta的交流分类
ta的全部笔记
浏览(1531)|(0)
&&交流分类:|笔记分类:
java lucene全文搜索引擎如何实现同义词分词器?
可以这样来实现:
其中samewordContext 是你的同义词类,封装一个map&1、自定义分词器
java代码:
public class MySameyzer extends yzer {
private SamewordContext samewordC
public MySameyzer(SamewordContext swc) {
samewordContext =
public TokenStream tokenStream(String fieldName, Reader reader) {
Dictionary dic = Dictionary.getInstance(&D:\\tools\\javaTools\\lucene\\mmseg4j-1.8.5\\data&);
return new MySameTokenFilter(
new MMSegTokenizer(new MaxWordSeg(dic), reader),samewordContext);
2、自定义过滤器
java代码:
public class MySameTokenFilter extends TokenFilter {
private CharTermAttribute cta =
private PositionIncrementAttribute pia =
private AttributeSource.S
private Stack&String& sames =
private SamewordContext samewordC
private OffsetAttribute ofa =
protected MySameTokenFilter(TokenStream input,SamewordContext samewordContext) {
super(input);
cta = this.addAttribute(CharTermAttribute.class);
pia = this.addAttribute(PositionIncrementAttribute.class);
sames = new Stack&String&();
this.samewordContext = samewordC
public boolean incrementToken() throws IOException {
if(sames.size()&0) {
//将元素出栈,并且获取这个同义词
String str = sames.pop();
//还原状态
restoreState(current);
cta.setEmpty();
cta.append(str);
//设置位置0
pia.setPositionIncrement(0);
if(!this.input.incrementToken())
if(addSames(cta.toString())) {
//如果有同义词将当前状态先保存
current = captureState();
private boolean addSames(String name) {
String[] sws = samewordContext.getSamewords(name);
if(sws!=null) {
for(String str:sws) {
sames.push(str);
来自:/read-htm-tid-67538.html
相关笔记推荐
精品视频课程推荐
JavaScript的内置对象--Array、String、Date、Math等,可以通过DOM对象进行对象控制,创建控制菜单及复选框的控制,创建二级联动列表框及列表框选项的移动,JavaScript项目,创建基于JS的商品管理系统。
内容概述:Shiro是目前最热门、最易用、功能超强大的Java权限管理框架,强烈推荐,每个项目都必备的权限管理技术!通过本课程,你将从零开始直到彻底掌握Shiro的相关开发知识,达到可以进行实际项目开发的能力。包括:权限管理基础、Shiro入门、配置、身份认证、授权、Realms、Session管理、和Spring的集成、Web、Cache等众多开发细节技术
技术要点:源码级分析Shiro的授权过程、自定义开发Realm、多个Realms的开发配置、自定义开发AuthenticationStrategy、自定义开发自定义SessionDAO、和Struts2+Spring3的集成(包括修正struts2的bug)、Shiro和SpringMVC+Spring3的集成、包装使用其他的Cache框架、缓存数据同步更新的解决方案等等实际开发中常用的内容
系统、完整的学习Spring Web MVC开发的知识。包括:Spring Web MVC入门;理解DispatcherServlet;注解式控制器开发详解;数据类型转换;数据格式化;数据验证; 拦截器;对Ajax的支持;文件上传下载;表单标签等内容;最后以一个综合的CRUD带翻页的应用示例来综合所学的知识
从零到精通Spring3的开发知识;IoC/DI的思想、IoC/DI的运行流程、IoC/DI的开发指导、AOP的思想、AOP的运行流程、AOP应用的设计、Spring对JDBC和Hibernate的支持、Spring的事务、SSH的集成应用
学习在java项目中使用log4j、jdk自带的日志框架和slf4j
浏览(1531)|(0)
&&交流分类:|笔记分类:
版权所有 Copyright(C) 私塾在线学习网14261人阅读
1.为什么专注于而不是?
一、首先,人讨厌
对任何一名忠实的来说,我们都不会喜欢复杂的代码结构,都不会喜欢解决那些因繁琐的指针、引用所衍生的神奇Memory问题,更难以接受代码和资源稍微多些,重新编译一次工程就要耗费数分钟乃至数小时的恐怖煎熬。
尽管Java语法脱胎于C/C++,且现阶段在运行上也离不开C/C++构建的JVM。但我们却真的不喜欢直接用C/C++编程,否则,也不会选择这条与C相似,却不尽相同的道路。
坦率地说,绝大多数人对于有着本能般的排斥,就连开发方式,我们也会尽量少的使用。
强迫我们使用会让我们非常痛苦,强迫我们在非必要的场合使用简直让我们想去犯罪。
比如,小弟在Libgdx论坛“潜伏”时,就曾看到有Javaer对某C系游戏引擎大声疾呼:I hate it!
小弟在此敬告所有专职搞的女同志:多年后,我若搞,你若玩,&让你闺女还有你在路上注意点(╯^╰)。
二、其次,在游戏开发上也有其局限性
虽然从运行效率上看,系语言编写的游戏会比语言编写的游戏运行效率为高。然而,这却是以单纯开发的低兼容性,高难度,漫长开发周期为代价的。
可能有人会说:别扯了,张嘴你丫就胡说!不是能“一次编写,到处编译”吗?怎么会扯到兼容性问题上呢?
——拜托,有脑子的话,请让它稍微运动一下好吗?
如果C++真的能“一次编写,到处编译”,当年Sun为又凭什么让Java一举成名,最高市值达到2100亿美金的巅峰?如果C++真的能“一次编写,到处编译”,那苹果如今又为什么要搞LLVM这个“特殊的虚拟机”出来(虽然对外仅仅是“资助”关系),补足IOS系统呢?
关键原因就在于,单纯C/C++开发对系统底层的依赖实在太高,太高了。以至于,只要底层稍有变动,单纯的C/C++项目就随时可能瘫痪死掉。
远的不提,就说当初升级那么一次,顷刻便干躺下一片游戏引擎,他们的作者一直要耗到数周乃至数月后升级引擎代码才勉强解决了兼容问题。然而,基于的应用们,则普遍不存在这种困扰,甚至对此事根本毫无觉察。
对Java来说,无论系统底层如何修改,只要上层虚拟机的API不换,应用都可以准确无误的运行下去。退一万步讲,即使部分后台源码被更换了,对我们而言通常也就是换个类,甚至换个函数名的事。然后C/C++却不一样,C/C++在开发上牵一发而动全身,一个指针的错误使用,都可能让你的程序在莫名其妙的时刻莫名其妙的崩掉。更何况是不知牵扯到何处的底层变动了,将遭遇到的种种问题,远比Java用户所能遭遇到的问题要多得多。
或者有人会说,我用的引擎很高级,是源自的,或者山寨自的,他们有数十人的专业团队,有上千万的资金支持,所有可能的问题都已经被他们解决了,用他们的引擎——绝对不存在任何兼容性问题。
那么,小弟只反问您一句,就一句话。
就算他们能做到,您确信,您也可以做到吗???
事实上,即便你所使用的引擎本身没有任何兼容问题,但作为引擎用户的你,在开发中,也能做到绝对不产生兼容性问题吗?&
要知道,用开发时,只要稍不留神,手轻轻那么一滑,就可能写出在这个平台能用,那个平台不行的代码来,而你书写的代码量越大,这种可能性也就变得越高。
小弟愚见,在这世上号称可以多平台运行的语言中,有两种最为悲剧,一者为,一者为。
让这两个家伙跨平台运行的代价,在写过一定数量的跨平台代码后恐怕都会印象颇深吧?虽然他们在最终的最终,确实可以实现所谓的“跨平台运行”,但这中间的艰辛困苦,又有几人明了?真是“光看见贼吃肉,没看见贼挨打”啊!
仔细说来,为什么游戏引擎大多会青睐于,这些脚本引擎?为什么即使的功能已经十分完善,还要将它们引入其中,就像生怕你们使用而非脚本来进行开发一样呢?
这里的潜台词恐怕是“大哥,大姐们,兄弟好不容易才搞定这个C/C++引擎支持多平台运行,你们玩玩脚本就好,可千万别改我的C/C++代码啊!千万别改!你们一改,一改,就该改崩了~”
所以,即使你代码写的再好,只要使用开发,一旦所在平台底层代码有了变动,就绝对逃不出“一次编写,到处编译,平台升级,编译失败,重新编写,重新编译,平台又改,循环重来……”的变态连锁,这无疑是其低兼容性的体现。
总之水很深,不提也罢(-____-)。
再者,编译之耗时大家有目共度,而且代码越多耗时越大,对于代码量小的简单项目还好说,您大可以做会眼保健操什么的等待它结束。而一旦处理代码和资源都较多的中等以上规模项目(比如搞个怪物猎人之类),您又偏偏喜欢按下【重新编译】而非【编译】按钮。那么,您真的可以扭头回家,等明天再来看有啥编译结果吧(结果第二天一看,一万多个编译错误,十几万个警告之类(°&?°)~)
小弟经常在想,如果或是某个人单独负责的项目,而他又将所有开发资源都引入一个中,那么他每次按下重新编译,是不是公司都会给他放一次大假呢?\(╯-╰)/
由此可见,C/C++作为游戏开发语言,远非大家想象中那么十全十美。
三、最后,脚本语言才是游戏开发的王道,而本身就是很棒的脚本
通过前文的论述,大家可以发现,即便在今天,大多数C/C++开发的游戏引擎若没有像lua这类脚本引擎相配合,也很难制作出多么复杂的游戏来。
也正因为有了,之类的脚本引擎,才让的游戏开发周期由【数年】缩短为【数月】,才有效减少了程序员对代码的反复编译调试,才可以让脚本动态调用写成的基础类库,从而拓展出崭新的高级功能,而不必考虑一改就不兼容的问题……
可以说,有了脚本语言,才局部解决了上述所涉及的纯开发问题。
脚本引擎的诞生,缩短了C/C++游戏的开发时间,提高了代码的重用可能,使得大中型C/C++游戏能够较为轻松的实现。对于C/C++开发的游戏引擎而言,lua这样的脚本引擎真的至关重要,更可以说是无可替代。
然而,如果我们用来制作游戏引擎呢?我们还需要这样的脚本引擎辅助吗?
——答案,当然是,不需要了!
显而易见的,对于开发者来说,肯定没有对于那么重要。或者说,在某种程度上讲,本就是和平级的东西(有编译过程,产生,但同时又使用虚拟机解释执行,解释执行是脚本语言的特性,故此严格意义上说等于解释编译共存,单纯把它当脚本用没什么)。
譬如我们以开发时,哪怕重新编译上万个,也不过是一瞬间的事情,这是编译的速度所无法比拟的,脚本才有这种优势。而语法又比简洁很多,只要掌握一些基本方式,任何人都能用它轻易开发游戏(游戏存世量少,是最初开发偏向造成的,而不是不适合做游戏,否则就不能解释海量游戏的存在(另,拆过一些工程发现,有些排行很高的游戏纯是游戏换图移植))。
我们完全可以说,以代码充当游戏脚本,和使用脚本是没有本质区别的;即使偏要说有,也只是可能会让开发变得更慢,而非更快,毕竟很多面向对象的特性并不具备。
现实中的例子也是这样,著名的引擎当前总共支持三种开发语言:,,,而其最常用到的,在各种意义上都和平级。更进一步讲,只要愿意引入,它便可以立刻支持开发(基于,所以能凭借做支持)。
假如您认为在设计上不算脑残的话,那么使用做为游戏开发语言便同样是最正常不过的选择。
——当然,有两种特殊状况存在:一是您要移植已经使用引擎的游戏项目,二是您需要和他人分工开发,但对方却只会脚本。那就另当别论。
但世界中还有和等更加易用的动态语言项目存在,就算有人认为新一代动态语言相比老旧的更为高效,也大可用它们直接补上,而不必借助。
综上所述,利用Java充当游戏脚本,充当游戏开发语言绝不是什么奇谈怪论,而是非常容易做到,也必将做到的事情。
2.Java游戏引擎前进的道路上面临着哪些障碍?
有优势当然也会有劣势,在智能机领域中,游戏引擎所面临的问题也真不少,否则早该由语言一统天下,而论不到逞强撒野了。
一、Oracle不给力,标准目前不能支持任何一款知名智能机平台
假如Oracle提供多智能机平台支持,让Java游戏爆炸式增长,根本就轻而易举。MonoTouch就放在那里,多平台支持根本不会存在技术障碍,真做不了还可以买下换壳嘛。
真正的大问题是,Oracle似乎对移动领域根本就没有兴趣(至少在行动上),以至平白错过了智能机发展时代,还懵懂未明。
悉数目前最有发展潜力,也最知名的三大智能机平台,莫过于:、、、、脑残黑)。
抛开主观意图不谈,我们只说凭借多年来积累下的“江湖地位”,&究竟能部署到哪一个上呢?
Google的?不可能。
世人皆知,已经让埃里森得罪苦了(犹太人别打犹太人啊),标准想上不说是做梦,但除非和全体员工同老板一起嗑药,然后一起滚床单高喊。否则,这也算得上天方夜谭了(何况自己的Dalvik还活着呢)。
Microsoft的?不能实现。
至于平台,额滴神啊,人家有自己的,怎么轮得到插手。假如我是埃里森,倒很可能拼着丢个几亿出去买下,然后闭源部分,让它彻底沦为项目再开源,同时免费三年,真不信搞不定(三年后考下认证的可以免费用,考不下的一年使用费)。
可惜,埃里森成不了我,我也成不了埃里森,所以,全是做梦。
Apple的?听说埃里森和天国的乔布斯,当年私交好到两人老婆都妒忌啊。
仔细斟酌下,小弟发现以的人缘江湖地位,现阶段唯一有可能上的知名智能机平台(个人愚见,真心不算智能机,没有这货不可能成功),似乎只剩下的了。
尤其在很多年前,当刚刚出现之时,就有人迫不及待的上传了下面这样一张图片。不得不说,当时很多都倍感鼓舞,以为终于能跑在上了。
“岁月是把杀猪刀,喝了咖啡,黑了龟壳,收了老乔”
但接下来的发展,却让人不再乐观,尽管人们都期待着看到跑在上的飒爽英姿。但换来的,却是一次又一次的疯狂跳票。
从年的,几乎的字眼就从没间断过,如今已近年了(如果年地球不便当),传说中的却连个测试版也没有踪影。
此刻我们再看公布的发展路线图,连的影子都找不到了。
大哥,把你手里中运行的项目上传先,都三年了。此刻我只能说——毫无痕迹啊。
Oracle啊!!你真不愧是传说中的坑神,专注坑爹年!画个圈圈咀咒你╰_╯)
二、自行开发多平台支持标准不统一,各师各法
因为跪了,们不得不纷纷自谋生路,自己想办法解决应用的智能机移植问题。
不过嘛,这也没什么,并非Microsoft官方开发,照样可以干的风生水起。
——我们坚信,技术宅挽救世界。
遗憾的是,目前在世界中,还没有一款能同并驾齐驱的项目,更缺乏一个Xamarin那样的团队(与.NET能相较者倒有之~)。所以,当今最主流的跨平台方式,居然是依靠,然后通过这个扩展插件把语言转为能够接受的CIL再进行特有的本地化处理(虽然对的贡献也不少,但这只优化了,并没有产生自己的智能机跨平台项目)。
使用这种方式解决智能机跨平台移植的游戏引擎较多,比较有名的是支持的,以及个人主导开发的。
MonoTouch+IKVM的最大好处在于,原版程序只要经过很少的修改,就可运行于多种智能机平台之上。
PlayN&for&IOS版部分源码:
Libgdx&for&IOS&部分源码:
从代码上来说,两者都没对代码部分进行什么修改,仅仅以提供的本地替换了其原本的本地交互部分,就让程序正常跑在环境之上了。
以效果论,这堪称是目前最简洁,最便利的智能机平台开发方案。
——假如,不要钱的话。
虽然Mono项目本身是免费的,这个开发用IDE也是免费的,就连MonoGame这个仿实现都同样是免费的,但关键是——真正有价值的Mono衍生项目MonoTouch却是收费的!而且,此物还是Miguel&de&Icaza自己搞的,铁了心要收钱,绝对不会开源的商用项目!
上邪!企业版999(完全支持2499)美刀,个人版399美刀,至于free版的MonoTouch呢?除了能在模拟器玩一玩,再没有其他作用。
GameMaker正版授权能跑大平台,不过;价格不菲,其3D高质量却摆在眼前。而上一个Professional的授权便需,这实在让人难以接受。试问又有多少人会花(普通企业版999$),只为跑个免费的游戏引擎呢?难道不知道,一台的价格,便足以让某些国家的人缺少肾脏之类的身体重要器官吗?!
而MonoTouch,又是目前以KIVM+Mono方式让Java支持智能机多平台开发的唯一手段。
My&God&!谁会花几百刀就为用个开源引擎(收费引擎大多还有破解版),谁就真脑子被驴踢了。IKVM这条路,恐怕是很难走下去了(土豪请自觉退散)。
故此,小弟对Libgdx和这种开源引擎,采用作为跨平台解决方案的评价只有四个字。
——浪费时间。
既然这个高富帅靠不住,我们只好退而求其次,找找系本身有没有什么和类似,可以把源码本地化,却不收费的穷人乐项目存在。
幸运的是,在世界中确实有这么一个项目,它,就是传说中的。
XMLVM并不是标准的实现,它基于的实现部分,而非之类。
就原理来说,XMLVM酷似,都是先将原始文件转化为某种中间代码,再将中间代码本地化到指定平台的交叉编译工具。
从适用范围上讲,其实比还要广阔,XMLVM可以将任意ava字节码或&CIL乃至翻译成文档,再转化为,,,等等很多种语言输出,这点是所无法比拟的。当然,它最核心,也是最常用的目地,&还是让转化为任意语言并本地编译。
通过源自的官方描述我们可以看到,就连一直说要搞定而没有搞定的,也在支持之列。
虽然功能上还有所欠缺,不过想把转化为或都可以做到(另,人家注明要抛弃了)。
可以说,您何时愿意使用,您何时就可以让自己的程序跑在系统之上。
——不过也是有缺点的。
下面,是一个XMLVM将转化为时产生的文件。
大家可以看到,Java代码确实被转化成了文件,而且这个文件也确实是可以被编译通过的。但是,为什么语法看上去那么奇怪,好像有多冗余在其中呢?……
原因就在于,XMLVM对于或的文件转化并非基于源码,而是基于源码所衍生的或指令集。
显然,是将比源码更简单的,面向过程的指令集转化到目标源码之上,而非源码对源码的迁移。但这毕竟不是汇编,无论你的初衷怎样,用面向对象的方式,写等价于指令集的代码,都会造成某些一些很不必要的冗余代码。
——&效率是硬伤。
对于结构复杂的代码转化成的代码,程序性能将会被严重拉低。
——低到和原版差别不大的程度原本的代码毕竟是跑虚拟机,这样看来问题不算太大嘛,。
XMLVM发展到年,已经可以满足绝大多数代码向,,的迁移。如果能把效率问题更优化一些,减少些转化可能引发的问题,更多地增加本地。那么,超越也指日可待(大部分代码可以转化成功,但非能够成功,在使用时也可能出现必须修改源码以适应的情况存在。比如小弟的整体可以转化,但有个别函数无法生成可用方法,如果替换写法应该能解决。不过,我还是等再成熟点自然解决吧,先搞自己的多平台方案玩……)。
PS:另外还有这种基于的二次开发项目。这货不是单纯的衍生,而是重写了部分实现替换以自己的类库,而且自带和可视化插件,做应用的话堪称神物。比较郁闷的是,它重写了一堆组件,用统一的掩盖了本地,让人看着不爽,做游戏引擎的话,有些东西我想自己改的
对了,最近类似的项目又新增了作者搞的,这是一个的转化工具,一样基于字节码向本地语言的迁移(所以翻译过来的代码看上去也一样奇葩)。
话说果然都是技术宅,宁愿自己写新的,也不愿意去参加项目&_&|||)。
最后,我们来谈谈前几天横空出世的。
J2ObjC,搞的一神物,作用是将代码无缝转化为代码。
与的区别在于,它并不是翻译字节码,而是真的将语法做的移植,这样它所生成的,文件将具有可读性,也方便用户自行改写指令集是面向过程的,而源文件的书写方式是面向对象的,有编码习惯在起作用,转化指令集比转化源码翻译简单的多,因为复杂源码是很难按面向对象翻译准确的。
比较遗憾的是,已明确表示不提供界面以及一切与本地交互的功能,只保证语法的迁移。需要界面之类的,那部分还得自己手写本地代码去(这是在逼人发展的衍生项目啊)。
不过嘛,这对小弟来说已经足够了,因为小弟目前已经在做特定范围内的功能再现与自有集(就是版到其它版本的转换器,话说这货快调完了,版目前已经冻结,正向其它版本迁移)。因为我原先做的已经有,加上的,彻底省事了……
总之,作为智能机领域游戏开发语言,在技术上是绝对可以实现的,前途是光明的。
__________________________
在的中有更新,目前版已经冻结,只要完整像其它版本的新增类和迁移就可以发布了(顺便我先重写部分版,旧版有部分地方还是坑爹),并且增加了一些示例源码(如下图所示,两款镇场用的未包括,等正式发布时再加):
版权声明:本文为博主原创文章,未经博主允许不得转载。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:2042760次
积分:24645
积分:24645
排名:第109名
原创:318篇
转载:66篇
评论:5485条
(1)(2)(1)(5)(3)(4)(1)(3)(4)(5)(3)(1)(1)(2)(1)(3)(2)(3)(3)(2)(2)(7)(1)(1)(3)(2)(10)(11)(14)(7)(11)(29)(4)(4)(11)(7)(5)(5)(9)(3)(10)(9)(2)(6)(11)(21)(21)(16)(16)(16)(8)(14)(7)(13)(7)(11)(1)(3)IBM Bluemix
点击按钮,开始云上的开发!
developerWorks 社区
本文对Java规则引擎与其API(JSR-94)及相关实现做了较详细的介绍,对其体系结构和API应用有较详尽的描述,并指出Java规则引擎,规则语言,JSR-94的相互关系,以及JSR-94的不足之处和展望
()南京大学计算机系
李国乐 曾在电信行业做过Java规则引擎及其API方面的研究应用工作,目前南京大学计算机科学与技术读研.电子邮件:,。
复杂企业级项目的开发以及其中随外部条件不断变化的业务规则(business logic),迫切需要分离商业决策者的商业决策逻辑和应用开发者的技术决策,并把这些商业决策放在中心数据库或其他统一的地方,让它们能在运行时(即商务时间)可以动态地管理和修改从而提供软件系统的柔性和适应性。规则引擎正是应用于上述动态环境中的一种解决方法。本文第一部分简要介绍了规则引擎的产生背景和基于规则的专家系统,第二部分介绍了什么是规则引擎及其架构和算法,第三部分介绍了商业产品和开源项目实现等各种Java规则引擎,第四部分对Java规则引擎API(JSR-94)作了详细介绍,讲解了其体系结构,管理API和运行时API及相关安全问题,第五部分则对规则语言及其标准化作了探讨,第六部分给出了一个使用Java规则引擎API的简单示例,第七部分给予小结和展望。1、 介绍1.1 规则引擎产生背景企业管理者对企业级IT系统的开发有着如下的要求:(1)为提高效率,管理流程必须自动化,即使现代商业规则异常复杂(2)市场要求业务规则经常变化,IT系统必须依据业务规则的变化快速、低成本的更新(3)为了快速、低成本的更新,业务人员应能直接管理IT系统中的规则,不需要程序开发人员参与。而项目开发人员则碰到了以下问题:(1)程序=算法+数据结构,有些复杂的商业规则很难推导出算法和抽象出数据模型(2)软件工程要求从需求-&设计-&编码,然而业务规则常常在需求阶段可能还没有明确,在设计和编码后还在变化,业务规则往往嵌在系统各处代码中(3)对程序员来说,系统已经维护、更新困难,更不可能让业务人员来管理。基于规则的专家系统的出现给开发人员以解决问题的契机。规则引擎由基于规则的专家系统中的推理引擎发展而来。下面简要介绍一下基于规则的专家系统。<h3 id="N1 基于规则的专家系统(RBES)专家系统是人工智能的一个分支,它模仿人类的推理方式,使用试探性的方法进行推理,并使用人类能理解的术语解释和证明它的推理结论。专家系统有很多分类:神经网络、基于案例推理和基于规则系统等。RBES包括三部分:Rule Base(knowledge base)、Working Memory(fact base)和Inference Engine(推理引擎)。它们的结构如下所示:图1.基于规则的专家系统组成如上图所示,推理引擎包括三部分:Pattern Matcher、Agenda和Execution Engine。Pattern Matcher何时执行哪个规则;Agenda管理PatternMatcher挑选出来的规则的执行次序;Execution Engine负责执行规则和其他动作。推理引擎通过决定哪些规则满足事实或目标,并授予规则优先级,满足事实或目标的规则被加入议程。
存在两者推理方式:演绎法(Forward-Chaining正向链)和归纳法(Backward-Chaining反向链)。演绎法从一个初始的事实出发,不断地应用规则得出结论(或执行指定的动作)。而归纳法则是从假设出发,不断地寻找符合假设的事实。2、 规则引擎<h3 id="N1 业务规则一个业务规则包含一组条件和在此条件下执行的操作,它们表示业务规则应用程序的一段业务逻辑。业务规则通常应该由业务分析人员和策略管理者开发和修改,但有些复杂的业务规则也可以由技术人员使用面向对象的技术语言或脚本来定制。业务规则的理论基础是:设置一个或多个条件,当满足这些条件时会触发一个或多个操作。2.2 规则引擎什么是规则引擎?规则引擎是如何执行规则的?这可以称之为"什么"与"如何"的问题。到底规则引擎是什么还是目前业界一个比较有争议的问题,在JSR-94种也几乎没有定义。可以这样认为充分定义和解决了"如何"的问题,"什么"问题本质上也迎刃而解。也许这又是一种"先有蛋还是先有鸡"哲学争论。今后标准规则语言的定义和推出及相关标准的制定应该可以给这样的问题和争论划上一个句号。本文中,暂且这样述说什么是规则引擎:规则引擎由推理引擎发展而来,是一种嵌入在应用程序中的组件,实现了将业务决策从应用程序代码中分离出来,并使用预定义的语义模块编写业务决策。接受数据输入,解释业务规则,并根据规则做出业务决策。<h3 id="N1 规则引擎的使用方式由于规则引擎是软件组件,所以只有开发人员才能够通过程序接口的方式来使用和控制它,规则引擎的程序接口至少包含以下几种API:加载和卸载规则集的API;数据操作的API;引擎执行的API。开发人员在程序中使用规则引擎基本遵循以下5个典型的步骤:创建规则引擎对象;向引擎中加载规则集或更换规则集;向引擎提交需要被规则集处理的数据对象集合;命令引擎执行;导出引擎执行结果,从引擎中撤出处理过的数据。使用了规则引擎之后,许多涉及业务逻辑的程序代码基本被这五个典型步骤所取代。 一个开放的业务规则引擎应该可以"嵌入"在应用程序的任何位置,不同位置的规则引擎可以使用不同的规则集,用于处理不同的数据对象。此外,对使用引擎的数量没有限制。2.4 规则引擎架构与推理规则引擎的架构如下图所示:图2. 业务规则引擎架构规则引擎的推理步骤如下:a. 将初始数据(fact)输入至工作内存(Working Memory)。b. 使用Pattern Matcher将规则库(Rules repository)中的规则(rule)和数据(fact)比较。c. 如果执行规则存在冲突(conflict),即同时激活了多个规则,将冲突的规则放入冲突集合。d. 解决冲突,将激活的规则按顺序放入Agenda。e. 执行Agenda中的规则。重复步骤b至e,直到执行完毕Agenda中的所有规则。任何一个规则引擎都需要很好地解决规则的推理机制和规则条件匹配的效率问题。当引擎执行时,会根据规则执行队列中的优先顺序逐条执行规则执行实例,由于规则的执行部分可能会改变工作区的数据对象,从而会使队列中的某些规则执行实例因为条件改变而失效,必须从队列中撤销,也可能会激活原来不满足条件的规则,生成新的规则执行实例进入队列。于是就产生了一种"动态"的规则执行链,形成规则的推理机制。这种规则的"链式"反应完全是由工作区中的数据驱动的。 规则条件匹配的效率决定了引擎的性能,引擎需要迅速测试工作区中的数据对象,从加载的规则集中发现符合条件的规则,生成规则执行实例。1982年美国卡耐基·梅隆大学的Charles L. Forgy发明了一种叫Rete算法,很好地解决了这方面的问题。目前世界顶尖的商用业务规则引擎产品基本上都使用Rete算法。<h3 id="N1 规则引擎的算法大部分规则引擎产品的算法,基本上都来自于Dr. Charles Forgy在1979年提出的RETE算法及其变体,Rete算法是目前效率最高的一个Forward-Chaining推理算法,Drools项目是Rete算法的一个面向对象的Java实现,Rete算法其核心思想是将分离的匹配项根据内容动态构造匹配树,以达到显著降低计算量的效果。详情请见CIS587:The RETE Algorithm,The Rete Algorithm,RETE演算法,《专家系统原理与编程》中第11章等。3、 Java规则引擎目前主流的规则引擎组件多是基于Java和C++程序语言环境,已经有多种Java规则引擎商业产品与开源项目的实现,其中有的已经支持JSR94,有的正朝这个方向做出努力,列出如下:3.1 Java规则引擎商业产品 Java规则引擎商业产品主要有(Jess不是开源项目,它可以免费用于学术研究,但用于商业用途则要收费):3.2 Java规则引擎开源项目开源项目的实现主要包括:Drools - Drools规则引擎应用Rete算法的改进形式Rete-II算法。从内部机制上讲,它使用了和Forgy的算法相同的概念和方法,但是增加了可与面向对象语言无缝连接的节点类型。Mandarax 基于反向推理(归纳法)。能够较容易地实现多个数据源的集成。例如,数据库记录能方便地集成为事实集(facts sets),reflection用来集成对象模型中的功能。目前不支持JSR 94OFBiz Rule Engine - 支持归纳法(Backward chaining).最初代码基于Steven John Metsker的"Building Parsers in Java",不支持JSR 94JLisa - JLisa是用来构建业务规则的强大框架,它有着扩展了LISP优秀特色的优点,比Clips还要强大.这些特色对于多范例软件的开发是至关重要的.支持JSR 94其它的开源项目实现有诸如Algernon, TyRuBa, JTP, JEOPS, InfoSapient, RDFExpert, Jena 2, Euler, JLog, Pellet OWL Reasoner, Prova, OpenRules, SweetRules, JShop2等等。4、 Java规则引擎API(JSR-94)4.1 简介过去大部分的规则引擎开发并没有规范化,有其自有的API,这使得其与外部程序交互集成不够灵活。转而使用另外一种产品时往往意味需要重写应用程序逻辑和API调用,代价较大。规则引擎工业中标准的缺乏成为令人关注的重要方面。2003年11月定稿并于2004年8月最终发布的JSR 94(Java规则引擎API)使得Java规则引擎的实现得以标准化。Java规则引擎API由javax.rules包定义,是访问规则引擎的标准企业级API。Java规则引擎API允许客户程序使用统一的方式和不同厂商的规则引擎产品交互,就像使用JDBC编写独立于厂商访问不同的数据库产品一样。Java规则引擎API包括创建和管理规则集合的机制,在Working Memory中添加,删除和修改对象的机制,以及初始化,重置和执行规则引擎的机制。4.2 简介Java规则引擎API体系结构Java规则引擎API分为两个主要部分:运行时客户API(the Runtime client API)和规则管理API(the rules administration API)。4.2.1规则管理API规则管理API在javax.rules.admin中定义,包括装载规则以及与规则对应的动作(执行集 execution sets)以及实例化规则引擎。规则可以从外部资源中装载,比如说URI,Input streams, XML streams和readers等等.同时管理API提供了注册和取消注册执行集以及对执行集进行维护的机制。使用admin包定义规则有助于对客户访问运行规则进行控制管理,它通过在执行集上定义许可权使得未经授权的用户无法访问受控规则。管理API使用类RuleServiceProvider来获得规则管理(RuleAdministrator)接口的实例.规则管理接口提供方法注册和取消注册执行集.规则管理器(RuleAdministrator)提供了本地和远程的RuleExecutionSetProvider.在前面已提及,RuleExecutionSetProvider负责创建规则执行集.规则执行集可以从如XML streams, input streams等来源中创建.这些数据来源及其内容经汇集和序列化后传送到远程的运行规则引擎的服务器上.大多数应用程序中,远程规则引擎或远程规则数据来源的情况并不多见.为了避免这些情况中的网络开销,API规定了可以从运行在同一JVM中规则库中读取数据的本地RuleExecutionSetProvider.规则执行集接口除了拥有能够获得有关规则执行集的方法,还有能够检索在规则执行集中定义的所有规则对象.这使得客户能够知道规则集中的规则对象并且按照自己需要来使用它们。4.2.2 运行时API运行时API定义在javax.rules包中,为规则引擎用户运行规则获得结果提供了类和方法。运行时客户只能访问那些使用规则管理API注册过的规则,运行时API帮助用户获得规则对话并且在这个对话中执行规则。运行时API提供了对厂商规则引擎API实现的类似于JDBC的访问方法.规则引擎厂商通过类RuleServiceProvider(类RuleServiceProvider提供了对具体规则引擎实现的运行时和管理API的访问)将其规则引擎实现提供给客户,并获得RuleServiceProvider唯一标识规则引擎的URL.URL推荐标准用法是使用类似"com.mycompany.myrulesengine.rules.RuleServiceProvider"这样的Internet域名空间,这将有助于访问URL的唯一性.类RuleServiceProvider内部实现了规则管理和运行时访问所需的接口.所有的RuleServiceProvider要想被客户所访问都必须用RuleServiceProviderManager进行注册。注册方式类似于JDBC API的DriverManager和Driver。运行时接口是运行时API的关键部分.运行时接口提供了用于创建规则会话(RuleSession)的方法,规则会话如前所述是用来运行规则的.运行时API同时也提供了访问在service provider注册过的所有规则执行集(RuleExecutionSets).规则会话接口定义了客户使用的会话的类型,客户根据自己运行规则的方式可以选择使用有状态会话或者无状态会话。无状态会话的工作方式就像一个无状态会话bean.客户可以发送单个输入对象或一列对象来获得输出对象.当客户需要一个与规则引擎间的专用会话时,有状态会话就很有用.输入的对象通过addObject() 方法可以加入到会话当中.同一个会话当中可以加入多个对象.对话中已有对象可以通过使用updateObject()方法得到更新.只要客户与规则引擎间的会话依然存在,会话中的对象就不会丢失。RuleExecutionSetMetaData接口提供给客户让其查找规则执行集的元数据(metadata).元数据通过规则会话接口(RuleSession Interface)提供给用户。使用运行时Runtime API的代码片断如下所示:RuleServiceProvider ruleProvider =
RuleServiceProviderManager.getRuleServiceProvider
("com.mycompany.myrulesengine.rules. RuleServiceProvider");
RuleRuntime ruleRuntime = ruleProvider.getRuleRuntime();
StatelessRuleSession ruleSession = (StatelessRuleSession)
ruleRuntime.createRuleSession(ruleURL, null, RuleRuntime.STTELESS_SESSION_TYPE);
List inputRules = new ArrayList();
inputRules.add(new String("Rule 1"));
inputRules.add(new Integer(1));
List resultRules = ruleSession.executeRules(inputRules);4.3 Java规则引擎API安全问题规则引擎API将管理API和运行时API加以分开,从而为这些包提供了较好粒度的安全控制.规则引擎API并没有提供明显的安全机制,它可以和J2EE规范中定义的标准安全API联合使用.安全可以由以下机制提供,如Java authentication and authorization service (JAAS),the Java cryptography extension (JCE),Java secure Socket Extension (JSSE),或者其它定制的安全API.JAAS能被用来定义规则执行集的许可权限,从而只有授权用户才能访问。<h3 id="N1 异常与日志规则引擎API定义了javax.rules.RuleException作为规则引擎异常层次的根类.所有其它异常都继承于这个根类.规则引擎中定义的异常都是受控制的异常(checked exceptions),所以捕获异常的任务就交给了规则引擎。
规则引擎API没有提供明确的日志机制,但是它建议将Java Logging API用于规则引擎API。<h3 id="N1 JSR 94 小结 JSR 94 为规则引擎提供了公用标准API,仅仅为实现规则管理API和运行时API提供了指导规范,并没有提供规则和动作该如何定义以及该用什么语言定义规则,也没有为规则引擎如何读和评价规则提供技术性指导.JSR 94规范将上述问题留给了规则引擎的厂商.在下一节我将简要介绍一下规则语言。5、 规则语言JSR 94中没有涉及用来创建规则和动作的语言.规则语言是规则引擎应用程序的重要组成部分,所有的业务规则都必须用某种语言定义并且存储于规则执行集中,从而规则引擎可以装载和处理他们。由于没有关于规则如何定义的公用规范,市场上大多数流行的规则引擎都有其自己的规则语言,目前便有许多种规则语言正在应用,因此,当需要将应用移植到其他的Java规则引擎实现时,可能需要变换规则定义,如将Drools私有的DRL规则语言转换成标准的ruleML,Jess规则语言转换成ruleML等。这个工作一般由XSLT转换器来完成。规则语言的详情这里不作详细介绍,名称及其网址列出如下:Rule Markup language (RuleML)
http://www.ruleml.org/
Simple Rule Markup Language (SRML)
http://xml.coverpages.org/srml.html
Business Rules Markup Language (BRML)
http://xml.coverpages.org/brml.html
SWRL: A Semantic Web Rule Language Combining OWL and RuleML
http://www.daml.org/2003/11/swrl/多种规则语言的使用使得不同规则引擎实现之间的兼容性成为问题.通用的规则引擎API或许可以减轻不同厂家API之间的问题,但公用规则语言的缺乏将仍然阻碍不同规则引擎实现之间的互操作性.尽管业界在提出公用规则语言上做出了一些努力, 比如说RuleML,SRML的出现,但距离获得绝大部分规则引擎厂商同意的公用标准还有很长的路要走。6、 Java规则引擎API使用示例 <h3 id="N1 设置规则引擎Java规则引擎的管理活动阶段开始于查找一个合适的javax.rules.RuleServiceProvider对象,这个对象是应用程序访问规则引擎的入口。在J2EE环境中,你可能可以通过JNDI获得RuleServiceProvider。否则,你可以使用javax.rules.RuleServiceProviderManager类:
javax.rules.RuleServiceProviderManager class:
String implName = "org.jcp.jsr94.ri.RuleServiceProvider";
Class.forName(implName);
RuleServiceProvider
serviceProvider = RuleServiceProviderManager.getRuleServiceProvider(implName);拥有了RuleServiceProvider对象,你就可以获得一个javax.rules.admin.RuleAdministrator类。从RuleAdministrator类中,你可以得到一个RuleExecutionSetProvider,从类名可以知道,它用于创建javax.rules.RuleExecutionSets对象。RuleExecutionSet基本上是一个装入内存的,准备好执行的规则集合。包javax.rules.admin包括两个不同的RuleExecutionSetProvider类。RuleExecutionSetProvider类本身包括了从Serializable对象创建RuleExecutionSets的方法,因此在规则引擎位于远程服务器的情况下,仍然可以使用RuleExecutionSetProvider类,构造器的参数可以通过RMI来传递。另一个类是LocalRuleExecutionSetProvider,包含了其他方法,用于从非Serializable资源(如java.io.Reader-本地文件)创建RuleExectionSets。假设拥有了一个RuleServiceProvider对象,你可以从本地文件rules.xml文件创建一个RuleExectionSet对象。如以下的代码所示:RuleAdministrator admin = serviceProvider.getRuleAdministrator();
HashMap properties = new HashMap();
properties.put("name", "My Rules");
properties.put("description", "A trivial rulebase");
FileReader reader = new FileReader("rules.xml");
RuleExecutionSet ruleSet =
LocalRuleExecutionSetProvider lresp =
admin.getLocalRuleExecutionSetProvider(properties);
ruleSet = lresp.createRuleExecutionSet(reader, properties);
} finally {
reader.close();
}接下来,你可以使用RuleAdministrator注册获得的RuleExecutionSet,并给它分配一个名称。在运行时,你可以用同一个名称创建一个RuleSession;该RuleSession使用了这个命名的RuleExecutionSet。参见下面的用法:admin.registerRuleExecutionSet("rules", ruleSet, properties);6.2 执行规则引擎在运行时阶段,你可以参见一个RuleSession对象。RuleSession对象基本上是一个装载了特定规则集合的规则引擎实例。你从RuleServiceProvider得到一个RuleRuntime对象,接下来,从javax.rules.RuleRuntime得到RuleSession对象。RuleSession分为两类:stateful和stateless。它们具有不同的功能。StatefulRuleSession的Working Memory能够在多个方法调用期间保存状态。你可以在多个方法调用期间在Working Memory中加入多个对象,然后执行引擎,接下来还可以加入更多的对象并再次执行引擎。相反,StatelessRuleSession类是不保存状态的,为了执行它的executeRules方法,你必须为Working Memory提供所有的初始数据,执行规则引擎,得到一个内容列表作为返回值。下面的例子中,我们创建一个StatefulRuleSession实例,添加两个对象(一个Integer和一个String)到Working Memory,执行规则,然后得到Working Memory中所有的内容,作为java.util.List对象返回。最后,我们调用release方法清理RuleSession:RuleRuntime runtime = rsp.getRuleRuntime();
StatefulRuleSession session = (StatefulRuleSession)
runtime.createRuleSession("rules", properties,
RuleRuntime.STATEFUL_SESSION_TYPE);
session.addObject(new Integer(1));
session.addObject("A string");
session.executeRules();
List results = session.getObjects();
session.release();7、 结束语 Java规则引擎API(JSR-94)允许客户程序使用统一的方式和不同厂商的规则引擎产品交互,一定程度上给规则引擎厂商提供了标准化规范。但其几乎没有定义什么是规则引擎,当然也没有深入到规则是如何构建和操纵的,规则调用的效用,规则与Java语言的绑定等方面。并且JSR-94在对J2EE的支持上也不足。规则语言的标准化,JSR-94的进一步的充实深化都有待研究。
参考资料 Expert Systems Principles and Programming(专家系统原理与编程)
Joesph Giarratano
Business Rule Exchange - the Next XML Wave
By Margaret ThorpeJSR 94: Java Rule Engine API
A Closer Look at the Java Rules Engine API (JSR 94)
Benoy JoseJava规则引擎的集成 starrynight用规则引擎替换代码 何仁杰 梁冰Implementing a Rule-Driven Service Oriented Architecture
Daniel C. Hayes
July 2003JSR-94, What Next? Daniel Selman:这里有数百篇关于 Java 编程各个方面的文章。加入 。查看开发人员推动的博客、论坛、组和维基,并与其他 developerWorks 用户交流。
developerWorks: 登录
标有星(*)号的字段是必填字段。
保持登录。
单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件。
在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。
所有提交的信息确保安全。
选择您的昵称
当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。昵称长度在 3 至 31 个字符之间。
您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。
标有星(*)号的字段是必填字段。
(昵称长度在 3 至 31 个字符之间)
单击提交则表示您同意developerWorks 的条款和条件。 .
所有提交的信息确保安全。
IBM PureSystems(TM) 系列解决方案是一个专家集成系统
通过学习路线图系统掌握软件开发技能
软件下载、试用版及云计算
static.content.url=/developerworks/js/artrating/SITE_ID=10Zone=Java technologyArticleID=162830ArticleTitle=Java规则引擎与其API(JSR-94)publish-date=}

我要回帖

更多关于 java 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信