webx—CommandDispatcher分发服务

一、简介

Command pattern是一套基于Spring Framework ,以Use Case为中心的框架。它糅合了几种经典的JavaEE设计模式,使应用开发者在实现Use Case时,能够更专注于商业逻辑本身。

结构图:

webx—CommandDispatcher分发服务_第1张图片



整个业务层都是用Spring框架来配置的。Spring是一种轻量的IoC的框架,使用Spring能够最大程度上保证业务逻辑不被污染

表现层调用业务逻辑层的流程图:

webx—CommandDispatcher分发服务_第2张图片

二、具体流程

1. 客户端

如何调用一个业务逻辑呢?对于业务逻辑的调用者(通常是表现层),完全不用关心这个业务逻辑是如何实现的。对客户端而言,它只能看到command dispatcher,如下图:
对需要调用业务操作的Web层组件,其内聚了一个CommandDispatcher,通过该dispatcher来完成业务的委派,但是这个commandDispatcher就是一个Bean,它存在于Spring容器之中(可以参考web层的模块ioc)。缺点在于web层被command所侵入,并且与业务实现在一定程度上发生了耦合。

webx—CommandDispatcher分发服务_第3张图片

步骤:

a)创建一个Command,填上业务逻辑所需要的参数。
b)将Command对象传递给CommandDispatcher,这样就完成了业务逻辑的调用。
c)如果需要,可以取得业务逻辑的返回结果。

// Step 1. 装配一个command,
//         command名称为"userCommand","userCommand"中有许多有关user的子命令,
//         而"registerUser"是其中的一个子命令。(子命令参数是可选的)
Command command = new CommandSupport("userCommand", "registerUser");

commandName.getParameters().put("name", "michael");
commandName.getParameters().put("password", "helloworld");
commandName.getParameters().put("email", "[email protected]");

// Step 2. 调用业务逻辑
Result result = getDispatcher().execute(command);

// Step 3. 处理返回结果
if (result.isSuccess()) {
    User user = (User) result.getModels().get("user");
    
    // 通常这类操作会返回数据库所创建的sequence ID。
    int id = user.getId();
    
    ...
} else {
    ResultCode errorCode = result.getResultCode();
    
    if (errorCode == UserResultCode.USER_ALREADY_EXISTS) {
        ...
    }
    
    ...
}

2. 服务端

服务端,它也不需要了解客户端的情况。服务端要做的,无非是从系统接收command的请求,然后执行相应的业务逻辑而已。

步骤:

a)创建ApplicationObject(即AO)。
实现ApplicationObject接口,但建议从ApplicationObjectSupport继承

public class LoginAO extends ApplicationObjectSupport {
}

b)执行

类似于WebX中的action,AO可以根据command中的event参数来自动调用相应的方法,例如 new CommandSupport("loginAO", "login"),那么,只要实现下面的方法即可

public Result doLogin() {
    Account user   = userManager.login(userId, password);
    Result  result = new ResultSupport();

    if (user == null) {
        result.setSuccess(false);
        result.setResultCode(
                LoginResultCode.INVALID_USER_OR_PASSWORD);
    } else {
        result.setDefaultModel("user", user);
    }

    return result;
}
如果没有提供event参数,或未匹配event,那么默认的doPerform()方法将被执行

3. CommandDispatcher 实现

CommandDispatcher是一个“分发器”。它的功能就是根据command的名字找到相应的业务逻辑对象,并执行之。每一个业务逻辑对象对应一个或一组相关的use case。例如:在用户管理系统中,用户的创建、删除、修改等操作可以看作一个use case,因而我们可以写一个业务逻辑对象——“UserManagementAO”——来处理这个use case。“AO”是“ApplicationObject”的缩写,每一个AO必须实现ApplicationObject接口。

CommandDispatcher有多种实现,以适应多种需要:



序号

CommandDispatcher的实现

说明

1.

Stateless Session Bean

(CommandDispatcherBean)

 

使用Stateless Session Bean来分发Command。该实现允许进行分布式的商业逻辑调用。

2.

Message-driven Bean

(CommandDispatcherClient)

通过Message-driven Bean来分发Command,通过JMS来发送Command请求。该实现允许进行异步的商业逻辑调用。

3.

Plain Javabean

(CommandDispatcherLogic)

通过普通的Javabean来分发Command。这个实现非常适合在非EJB的环境下调用商业逻辑。

4.

NOOP

(CommandDispatcherNoop)

不做任何事情的分发器。这个实现非常适合在程序的开发阶段,用来调试程序。或者当商业逻辑还未开发完成时,调用者可以利用该分发器来“调用”商业逻辑,以便调用者的代码可以被顺利地开发。

5.

Selector

(CommandDispatcherSelector)

该分发器可根据Command的内容来自动先择合适的其它CommandDispatcher。这样,我们就可以更方便地控制CommandDispatcher的行为。例如,在调用者完全不知情的情况下,将某个Command的处理转变为利用Message-driven bean来异步处理。


尽管有这么多种CommandDispatcher的实现,但是表现层完全不用了解这些细节。所有的CommandDispatcher都是通过spring来配置的


4. 小结

Command Pattern是基于request-response的模式。客户端创建command,服务端响应command并返回结果给客户端 —— 类似WEB层的模式。而客户端和服务端是通过command dispatcher来连接的。
这种模式有什么好处呢?
最大的好处,就是客户端和服务端完全分离。无论是Web-tier还是Biz-tier都不用了解command分发的细节 —— 这些细节对代码是透明的。
其次,所有的CommandDispatcher都是通过spring来配置的,因此也很容易创建新的CommandDispatcher模式。目前已经支持同步、异步等操作。
那么,这种模式有什么缺点呢?任何设计模式都有适用的场合,也有不利的一面。Command Pattern也不例外。
这种模式最大的缺点是,没有一种统一的方法,可以知道业务逻辑层所需要的参数个数、类型,同样也很难知道返回值的数量和类型。这样会增加客户端/服务端程序员交流的成本。

你可能感兴趣的:(webx—CommandDispatcher分发服务)