Jess Java API 与自动化测试框架介绍
1. Jess 简化 Java API 概述
Jess 库包含约 75 个公共类,但很多类 Jess 程序员很少使用。本部分仅列出最重要类的最重要方法,有助于初学者快速上手 Jess 库。以下是主要类及其方法介绍:
1.1 jess.Context
该类代表函数的执行上下文。若用 Java 编写 Jess 函数,
call
方法会传入
Context
对象,通过它可访问函数执行所在的
Rete
对象及相关变量的值。
-
public Rete getEngine()
:返回与调用代码相关的
Rete
对象。
-
public Value getVariable(String name)
:返回变量的值,参数为不带
?
或
$
前缀的变量名,可用于获取
defglobal
的当前值。
-
public void setVariable(String name, Value value)
:设置变量的值,第一个参数为不带
?
或
$
前缀的变量名。
1.2 jess.Fact
Fact
类代表 Jess 工作内存中的一个条目,是
ValueVector
的子类。
-
public Fact(String name, Rete engine)
:向
Rete
对象请求指定名称的模板,若不存在则创建一个有序模板,这是最常用的构造函数。
-
public Deftemplate getDeftemplate()
:返回
Fact
的
Deftemplate
,可获取
Fact
的名称、槽数量和槽名称。
-
public int getFactId()
:返回
Fact
的数字标识符,每个
Fact
都有一个。
-
public int getShadowMode()
:若不是影子事实,返回
Fact.NO
;否则根据影子事实类型返回
Fact.DYNAMIC
或
Fact.STATIC
。
-
public Value getSlotValue(String name)
:返回指定名称槽的值,有序事实有一个名为
__data
的单槽,包含一个项目列表。
-
public void setSlotValue(String name, Value value)
:按名称设置槽的值,不要对当前在 Jess 工作内存中的
Fact
调用此方法。
1.3 jess.Funcall
Funcall
是代表函数调用的特殊列表。若需从 Java 多次调用 Jess 函数且变化不大,构建
Funcall
对象并调用
execute
方法通常更高效。
-
public Funcall(String name, Rete engine)
:接受要调用的函数名称,函数在创建时不必已定义,只要在调用
execute
时已定义即可。
-
public Funcall arg(Value v)
:向
Funcall
追加一个参数,此方法返回修改后的
Funcall
对象,可链式调用。
-
public Value execute(Context context)
:使用给定的
Context
执行
Funcall
,若没有
Context
,可调用
Rete.getGlobalContext()
获取。
1.4 jess.Jesp
Jesp
是 Jess 解析器,若想让 Jess 从网络流或其他不寻常源读取输入,可使用此类。
-
public Jesp(java.io.Reader reader, Rete engine)
:接受一个
Reader
对象作为输入源,Jess 代码流将被执行并应用于给定的
Rete
对象。
-
public Value parse(boolean prompt)
:进行解析,返回最后一个表达式求值的结果。若
prompt
为
true
,在读取每个表达式前会将
Jess>
提示符打印到
WSTDOUT
路由器。
1.5 jess.JessEvent
使用
Rete
类的
setEventMask
方法请求后,Jess 在某些事情发生时会发送
JessEvent
对象作为通知。每个
JessEvent
都有一个类型表示发生的事情,以及一个提供更多信息的对象。
| 类型 | 对象类型 | 描述 |
|---|---|---|
| ACTIVATION | jess.Activation |
一个
defrule
被激活或停用
|
| CLEAR | jess.Rete |
执行了
(clear)
|
| DEFCLASS |
defclass
的名称
|
一个
defclass
被添加或移除
|
| DEFFACT | jess.Deffacts |
一个
deffacts
被添加或移除
|
| DEFGLOBAL | jess.Defglobal |
一个
defglobal
被添加或移除
|
| DEFINSTANCE | JavaBean |
一个
definstance
被添加或移除
|
| DEFRULE | jess.Defrule |
一个
defrule
被添加或移除
|
| DEFRULE_FIRED | jess.Activation |
一个
defrule
被触发
|
| DEFTEMPLATE | jess.Deftemplate |
一个
deftemplate
被添加或移除
|
| FACT | jess.Fact | 一个事实被断言或撤销 |
| FOCUS | 模块名称 | 模块焦点已更改 |
| HALT | jess.Rete |
执行了
(run)
|
| RESET | jess.Rete |
执行了
(reset)
|
| RUN | jess.Rete |
执行了
(run)
|
| USERFUNCTION | jess.Userfunction |
一个
Userfunction
被添加或移除
|
| USERFUNCTION_CALLED | jess.Userfunction |
一个
Userfunction
被调用
|
| USERPACKAGE | jess.Userpackage |
一个
Userpackage
被添加或移除
|
-
public int getType():返回事件类型,是上表中的常量之一。 -
public Object getObject():返回与事件相关的数据。 -
public Object getSource():返回事件的源,即生成它的Rete对象。
1.6 jess.JessListener
若想接收
JessEvent
,需实现此接口,其工作方式与
java.awt.event
包中的事件监听器类似。
-
public void eventHappened(JessEvent je) throws JessException
:处理事件类型的事件,这是此接口中唯一的处理方法,处理程序应测试
JessEvent
中的
getType()
方法来决定采取什么行动。
1.7 jess.PrettyPrinter
此类知道如何格式化许多 Jess 构造,使其对人类读者更友好。它使用访问者模式,有许多名为
visitXXX
的方法,但通常不需要使用。
-
public PrettyPrinter(Visitable v)
:参数可以是实现
Visitable
接口的任何 Jess 类的实例,包括
Deffacts
、
Deffunction
、
Defglobal
、
Defquery
、
Defrule
和
Deftemplate
。
-
public String toString()
:返回作为构造函数参数传入的构造的格式化版本。
1.8 jess.Rete
Rete
类是 Jess 最重要部分的外观类,有管理工作内存、议程、规则库等的方法。以下是一些重要方法:
-
public Rete(Object appObject)
:构造一个新的
Rete
对象,参数的
ClassLoader
用于加载
new
、
call
和
defclass
等命令使用的任何类。
-
public Rete()
:使用
this
作为应用程序对象。
1.8.1 处理事件
-
public void addJessListener(JessListener jel):注册一个JessListener以接收事件。 -
public void removeJessListener(JessListener jel):注销一个JessListener,使其不再接收事件。 -
public int getEventMask():获取当前事件掩码的值。 -
public void setEventMask(int mask):设置事件掩码,通常应使用|运算符将此值与getEventMask返回的值组合。
1.8.2 与 Jess 语言代码交换 Java 值
-
public void clearStorage():清除存储区域,使store对任何名称都返回null。 -
public Value fetch(java.lang.String name):检索之前使用store存储的对象。 -
public Value store(java.lang.String name, java.lang.Object val):以给定名称存储一个对象,对象在存储前会包装在Value对象中。 -
public Value store(java.lang.String name, Value val):以给定名称存储一个Value。
1.8.3 导入表
-
public java.lang.Class findClass(String clazz):根据类名,使用导入表得出完全限定名,若传入"String"作为参数,返回java.lang.String的Class。 -
public void importClass(String clazz):将完全限定类名添加到导入表。 -
public void importPackage(String pack):通过将包名添加到导入表来导入包中的每个类。
1.8.4 查找事物
有一组方法可从引擎中检索
Defrule
和
Deffacts
等构造的实例,都接受构造的名称作为参数,若名称不包含模块名,则使用当前模块的名称。
-
public Fact findFactByFact(Fact f)
:快速查找,可用于快速确定给定事实是否在事实列表中,若存在则获取其引用,参数是与要查找的事实相同的
Fact
。
-
public Fact findFactByID(int id)
:根据数字标识符查找事实,此方法非常慢,除非必要否则不要使用。
-
public Iterator listXXX()
:许多方法返回
java.util.Iterators
遍历 Jess 构造的集合,包括
listActivations
、
listDeffacts
、
listDefglobals
等。
1.8.5 等待规则触发
-
public Object getActivationSemaphore():返回此引擎的激活信号量,每当有激活出现时,激活信号量的监视器会被通知,因此可在此对象上调用wait(),只有当 Jess 准备触发规则时,wait()调用才会返回。 -
public void waitForActivations():直到议程上有规则准备触发才返回。
1.9 jess.RU
RU
代表
Rete Utilities
,是一个包含一些有用常量的通用类,大多数常量枚举了
Value.getType
允许的返回值,即不同类型的
Value
对象。最重要的常量有(均为静态、最终的
int
变量):
ATOM
(符号)、
EXTERNAL_ADDRESS
、
FACT
、
FLOAT
、
FUNCALL
、
INTEGER
、
LIST
、
LONG
、
MULTIVARIABLE
、
STRING
和
VARIABLE
。
-
public static String gensym(String prefix)
:返回以给定前缀开头的唯一符号,若 Java 代码自动生成 Jess 规则、变量或其他实体,且需要生成唯一名称,此方法很有用。
1.10 jess.Token
Token
类代表一组事实在 Jess 的 Rete 网络中一起传播的情况。
Rete.runQuery()
返回的迭代器或 Jess 中的
run-query
函数返回一系列
Token
对象,否则通常不需要处理此类。
-
public Fact getFact(int index)
:从
Token
中返回单个
Fact
,与规则中第一个模式匹配的事实索引为 0。
-
public int size()
:返回
Token
中的事实数量。
-
public Fact topFact()
:相当于
token.getFact(token.size() - 1)
。
1.11 jess.Value
这是一个重要的类,因为通过 Jess 传输的每个信息(数字、字符串、Java 对象)都包装在
jess.Value
实例或其子类中。
-
public Value(boolean b)
:构造一个布尔值对象(
TRUE
或
FALSE
符号之一)。
-
public Value(double d, int type)
:构造一个数值,类型可以是
INTEGER
或
FLOAT
。
-
public Value(int value, int type)
:构造一个数值,类型可以是
INTEGER
或
FLOAT
,使用
LongValue
类构造
LONG
类型的
Value
。
-
public Value(java.lang.Object o)
:构造一个包含 Java 对象的
Value
(类型为
EXTERNAL_ADDRESS
)。
-
public Value(java.lang.String s, int type)
:构造一个词法值,类型可以是
STRING
或
ATOM
。
-
public Value(Value v)
:复制一个值。
-
public Value(ValueVector f, int type)
:构造一个
LIST
类型的值。
-
public int type()
:返回此变量的类型,是
RU
中的常量之一。
-
public Value resolveValue(Context c)
:给定一个评估上下文,返回此
Value
的真实值,对于变量,指变量的值;对于包含函数调用对象的
Value
对象,调用函数并提供返回值。
-
public String atomValue(Context c)
:以符号形式返回此值的内容。
-
public Object externalAddressValue(Context c)
:以 Java 对象形式返回此值的内容。
-
public Fact factValue(Context c)
:以事实形式返回此值的内容。
-
public double floatValue(Context c)
:以数字形式返回此值的内容。
-
public Funcall funcallValue(Context c)
:以函数调用形式返回此值的内容。
-
public int intValue(Context c)
:以整数形式返回此值的内容。
-
public ValueVector listValue(Context c)
:以列表形式返回此值的内容。
-
public long longValue(Context c)
:以长整数形式返回此值的内容。
-
public double numericValue(Context c)
:以数字形式返回此值的内容。
-
public String stringValue(Context c)
:以字符串形式返回此值的内容。
-
public String variableValue(Context c)
:以字符串形式返回此值的内容(变量名)。
1.12 jess.ValueVector
ValueVector
是
Value
对象的列表,此类既可以直接使用,也可作为
Fact
和其他重要 Jess 类的基类,与
java.util.Vector
和
java.util.ArrayList
类非常相似,有容量和大小的概念。
-
public ValueVector()
:构造一个默认容量为 10 的
ValueVector
。
-
public ValueVector(int size)
:构造一个具有给定容量的
ValueVector
。
-
public ValueVector add(Value val)
:在
ValueVector
末尾添加一个新元素。
-
public Value get(int i)
:获取列表中位置
i
的条目。
-
public ValueVector remove(int i)
:从列表中移除给定索引处的项,将所有编号较高的元素下移。
-
public ValueVector set(Value val, int i)
:将位置
i
的条目设置为
val
。
-
public ValueVector setLength(int i)
:设置列表的大小,此索引及以上的
Value
对象不再是列表的一部分。
-
public int size()
:返回
ValueVector
中
Value
对象的数量。
2. Jess 自动化测试框架
在迭代开发中,自动化测试能让你确信每次添加或修改不会给先前正常工作的程序引入错误。修改代码后运行测试,可立即知道更改是否破坏了现有代码。拥有一套快速便捷的自动化测试套件有助于更快地编写更好的代码,这对于基于规则的编程和其他类型的编程同样适用。
2.1 架构
Jess 测试框架基于 Bourne shell 脚本,在类 UNIX 系统上易于使用,也可通过安装 Cygwin 等 UNIX 仿真工具包在 Windows 系统上使用,当然,也可以使用批处理文件编写自己的测试框架。
测试框架的整体架构使用一个顶级
tests
目录,包含几个模板子目录和每个测试的一个额外子目录。要添加测试,复制一个模板目录并编辑其中的文件。每个目录(包括顶级目录)都包含一个
Makefile
和一个名为
runtest.sh
的 shell 脚本,测试目录还包含其他文件。以下是添加任何测试之前框架的目录结构:
tests/
├── template1/
│ ├── Makefile
│ └── runtest.sh
├── template2/
│ ├── Makefile
│ └── runtest.sh
└── ...
综上所述,Jess 的 Java API 提供了丰富的功能和方法,可用于开发基于 Jess 的应用程序,而自动化测试框架则有助于保证代码的质量和稳定性。在实际开发中,可以根据具体需求选择合适的 API 方法和测试框架来提高开发效率和代码质量。后续,我们可以进一步探讨如何结合这些 API 和测试框架进行更复杂的应用开发。
Jess Java API 与自动化测试框架介绍
3. 操作步骤与示例
3.1 使用 Jess Java API 的操作步骤
-
创建 Rete 对象
:
-
若需要指定应用对象的
ClassLoader,可使用public Rete(Object appObject)构造函数。示例代码如下:
-
若需要指定应用对象的
import jess.Rete;
public class JessExample {
public static void main(String[] args) {
Object appObject = new Object();
Rete engine = new Rete(appObject);
}
}
- 若使用当前对象作为应用程序对象,可使用 `public Rete()` 构造函数。示例代码如下:
import jess.Rete;
public class JessExample {
public static void main(String[] args) {
Rete engine = new Rete();
}
}
-
注册事件监听器
:
-
首先实现
JessListener接口。示例代码如下:
-
首先实现
import jess.JessEvent;
import jess.JessListener;
import jess.JessException;
public class MyJessListener implements JessListener {
@Override
public void eventHappened(JessEvent je) throws JessException {
int type = je.getType();
Object object = je.getObject();
System.out.println("Event type: " + type + ", Object: " + object);
}
}
- 然后使用 `addJessListener` 方法注册监听器。示例代码如下:
import jess.Rete;
import jess.JessListener;
public class JessExample {
public static void main(String[] args) {
Rete engine = new Rete();
JessListener listener = new MyJessListener();
engine.addJessListener(listener);
}
}
-
存储和检索 Java 值
:
-
存储值使用
store方法。示例代码如下:
-
存储值使用
import jess.Rete;
import jess.Value;
public class JessExample {
public static void main(String[] args) {
Rete engine = new Rete();
String name = "myObject";
Object val = new Object();
engine.store(name, val);
}
}
- 检索值使用 `fetch` 方法。示例代码如下:
import jess.Rete;
import jess.Value;
public class JessExample {
public static void main(String[] args) {
Rete engine = new Rete();
String name = "myObject";
Value value = engine.fetch(name);
}
}
-
查找类
:
-
使用
findClass方法根据类名查找类。示例代码如下:
-
使用
import jess.Rete;
import java.lang.Class;
public class JessExample {
public static void main(String[] args) {
Rete engine = new Rete();
String clazz = "String";
Class<?> foundClass = engine.findClass(clazz);
}
}
-
等待规则触发
:
-
使用
waitForActivations方法等待规则触发。示例代码如下:
-
使用
import jess.Rete;
public class JessExample {
public static void main(String[] args) {
Rete engine = new Rete();
try {
engine.waitForActivations();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
3.2 添加 Jess 测试的操作步骤
-
复制模板目录
:从顶级
tests目录下选择一个模板目录进行复制。例如,复制template1目录:
cp -r tests/template1 tests/myTest
-
编辑文件
:进入复制后的目录
tests/myTest,编辑Makefile和runtest.sh文件以满足测试需求。 -
运行测试
:在
tests/myTest目录下运行runtest.sh脚本。
cd tests/myTest
./runtest.sh
4. 总结与展望
Jess 的 Java API 为开发者提供了强大的工具,能够方便地与 Jess 进行交互,实现基于规则的应用开发。通过使用这些 API 方法,可以管理工作内存、议程、规则库等,还能与 Java 代码进行数据交换。同时,自动化测试框架的存在保证了代码的质量和稳定性,让开发者在迭代开发中更加自信。
在未来的开发中,可以进一步探索如何更深入地利用 Jess Java API 实现复杂的规则引擎应用,例如结合机器学习算法进行规则的自动生成和优化。此外,还可以对自动化测试框架进行扩展,增加更多的测试用例和测试场景,以提高代码的健壮性。
以下是 Jess Java API 使用和测试框架操作的流程图:
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px
A([开始]):::startend --> B(使用 Jess Java API):::process
B --> C(创建 Rete 对象):::process
C --> D(注册事件监听器):::process
D --> E(存储和检索 Java 值):::process
E --> F(查找类):::process
F --> G(等待规则触发):::process
G --> H(使用自动化测试框架):::process
H --> I(复制模板目录):::process
I --> J(编辑文件):::process
J --> K(运行测试):::process
K --> L([结束]):::startend
Jess Java API 和自动化测试框架为开发者提供了丰富的功能和便利,合理利用它们可以提高开发效率和代码质量,为基于规则的应用开发带来更多的可能性。
超级会员免费看
618

被折叠的 条评论
为什么被折叠?



