Dorado 7 : 08. 智能方法适配(SEFC)

在实做Ajax的范例中,我们注意到Ajax.java中的代码中没有任何dorado的开发约定,它的样子和我们业务层的代码没有什么差别:

@Expose
public String toUpperCase(String str) {
	return "input:\n" + str + "\n\n" + "output:\n"
			+ str.toUpperCase();
}

@Expose
public int multiply(int num1, int num2) {
	return num1 * num2;
}

这是如何做到的呢?另外在multiply方法中dorado是怎么将我们的一个map对象分拆为num1和num2的呢?要解释这几个问题就有必要先了解一下Dorado7提供的职能方法适配功能。所谓职能方法适配是基于"约定优于配置"的设计思路而提供。这样在很多情况下我们不需要方法具有Dorado特性,也不需要引入Dorado的开发规范。由Dorado7自动判断这个方法中的各个参数以及返回值的用途。这是一种职能化的处理逻辑。这带给我们的好处:

  • 几乎不需要引入任何Dorado7的API。
  • 按照业务的需要而不是Dorado7的需要来为表现层编写代码。
  • 可以令Dorado7与后台业务逻辑之间的粘合层代码更加简洁、易读。

如Ajax范例中的toUpperCase,Browser向服务器端传递的参数是我们在action的parameter属性中定义的,因为传过来的是一个字符串,智能方法在适配的时候会发现toUpperCase方法的参数就是一个字符串类型的,这样它就自动认为你想调用的方法就是toUpperCase,并将parameter中的值作为str中的值传入。这个方法调用结束之后返回了一个字符串给外界,而ajax调用就自动的将这个返回值作为ajax调用的返回值,如toUpperCaseAction的onSuccess方法:

// @Bind #toUpperCaseAction.onSuccess
!function(self){
    dorado.MessageBox.alert(self.get("returnValue"));
}

在multiply范例中前台传入的是一个JSON对象,可以就认为是一个Map对象:

var parameter = {
	num1: nums[0],
	num2: nums[1]
};
action.set("parameter", parameter).execute(function(result) {
	dorado.MessageBox.alert(nums[0] + " * " + nums[1] + " = " + result);
});

这样后台就拿到一个Map参数,让后对ajax这个bean进行方法匹配,会发现其中没有完全匹配的,这个时候职能方法适配会将parameters中的参数拆开为num1,num2,这样就可以发现存在对应的multiply方法,并进行调用。并将结果作为ajax调用的结果返回到前台:

action.set("parameter", parameter).execute(function(result) {
	dorado.MessageBox.alert(nums[0] + " * " + nums[1] + " = " + result);
});

我们直接将这个result显示出来。multiply范例体现的是智能方法适配过程中map自动拆解的功能。

适配算法

上面我们通过Ajax范例对智能方法的适配规则有了一些基本的了解,下面总结一下适配算法。

首先智能方法适配按照参数名进行适配:
  • 即Dorado根据参数名来确定每个参数的作用。
  • 相对严谨的适配规则,但有时使不够业务化。例如对于AjaxAction的后端方法,其参数名必须为parameter。

如果按照上面的规则,toUpperCaseAction对应的Ajax方法就必须为如下的形式:

@Expose
public String toUpperCase(String parameter) {
	return "input:\n" + parameter + "\n\n" + "output:\n"
			+ parameter.toUpperCase();
}

这种方式有时候可能并不满足我们对业务方法的命名习惯,不利于Java代码的阅读。

按照参数类型进行适配

另外我们还可以根据参数的类型进行方法适配。即Dorado根据参数类型来确定每个参数的作用。它存在的问题是:当参数较为复杂时Dorado可能无法准确的判断个参数的作用。

混合式的适配规则(尚未提供)

即现根据名称规则进行一次适配,对于那些无法匹配的参数继续尝试通过类型规则进行适配。自动方法适配不会强行调用目标方法,当其认为适配可能存在歧义时会报错而不会继续执行方法调用。

Map

对于Map类的参数自动方法适配会尝试将其拆解,用其中的键值对与方法参数进行适配。

 

参考阅读:常见智能方法适配错误及解决