`
iamzhongyong
  • 浏览: 805300 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Activiti中的命令模式解析

    博客分类:
  • java
 
阅读更多

最近在看Activiti的源代码,发现是基于命令模式进行的开发,所以对于Command模式做了个了解。

什么是命令模式?

这个随便翻开一本模式的书,都有介绍,这里就不再冗余了。画一个Command的图,然后加一个例子吧,方法和类的命名加入了自己的理解。

1、模式的根本是把“行为的请求者”和“行为的处理者”分开,实现解耦;

2、实现Command的ConcreteCommand,有时候要跟进实际情况保存额外的状态信息,例如上下文等;

3、大多数请求响应的处理,可以使用Command模式来扩展;

4、缺点的话,就是如果涉及的命令很多的话,本来简单的命令几行代码的事情,但是利用了这个模式之后,就需要搞一个类去做了;

 

 

1
2
3
4
5
//需要执行的命令都在这里
public interface Command  {
    //命令的执行方法
    public void execute( ) ;   
}

 

1
2
3
4
5
6
7
8
9
10
11
public class ConcreteCommand implements Command{
    private CommandProcess receiver;   
    @Override
    public void execute() {
        this.receiver.doSomething();
    }
    public ConcreteCommand(CommandProcess receiver) {
        super();
        this.receiver = receiver;
    }  
}

 

1
2
3
4
5
6
7
8
9
10
//调用命令
public class CommandInvoker {  
    private Command command;       
    public void action(){
        command.execute();
    }
    public void setCommand(Command command) {
        this.command = command;
    }      
}

 

1
2
3
4
5
//命令的执行者
public interface CommandProcess {
 
    public String doSomething();
}

 

1
2
3
4
5
6
7
8
9
public class CommandProcessForWindows implements CommandProcess {
 
    @Override
    public String doSomething() {
        System.out.println("ReceiverCmdForWindows doSomething ");
        return "iamzhongyong windows";
    }
 
}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Client {
 
    public static void main(String[] args) {
        CommandInvoker invoker = new CommandInvoker();
 
        //确定命令的处理者,构建命令
        CommandProcess process = new CommandProcessForWindows();       
        Command command = new ConcreteCommand(process);
 
        invoker.setCommand(command);
        invoker.action();
    }
}

 

Activiti中的命令模式是咋样的?

看了源代码,发现应该是Command模式和责任链模式的结合,执行命令的之后,加入了迭代的成分在里面。

 

 

Command类,这个和标准的Command模式不同之处,就是execute方法中增加了CommandContext信息,这个类可以说是执行命令的上下文

1
2
3
4
5
public interface Command <T> {
 
  T execute(CommandContext commandContext);
 
}

 

ServiceImpl类,所有的服务类继承这个,其实就一个作用,持有CommandExecutor类,这个类是命令的请求者

1
2
3
4
5
6
7
8
9
10
11
12
public class ServiceImpl {
 
  protected CommandExecutor commandExecutor;
 
  public CommandExecutor getCommandExecutor() {
    return commandExecutor;
  }
 
  public void setCommandExecutor(CommandExecutor commandExecutor) {
    this.commandExecutor = commandExecutor;
  }
}

 

CommandExecutor这个是命令的执行,其中CommandConfig是命令的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public interface CommandExecutor {
 
  /**
   * @return the default {@link CommandConfig}, used if none is provided.
   */
  CommandConfig getDefaultConfig();
 
  /**
   * Execute a command with the specified {@link CommandConfig}.
   */
  <T> T execute(CommandConfig config, Command<T> command);
 
  /**
   * Execute a command with the default {@link CommandConfig}.
   */
  <T> T execute(Command<T> command);
 
}

 

这个是一个具体命令类,内部含义可以不用看,就是一个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/**
 * @author Joram Barrez
 */
public class DeleteDeploymentCmd implements Command<Void>, Serializable {
 
  private static final long serialVersionUID = 1L;
  protected String deploymentId;
  protected boolean cascade;
 
  public DeleteDeploymentCmd(String deploymentId, boolean cascade) {
    this.deploymentId = deploymentId;
    this.cascade = cascade;
  }
 
  public Void execute(CommandContext commandContext) {
    if(deploymentId == null) {
      throw new ActivitiIllegalArgumentException("deploymentId is null");
    }
 
    // Remove process definitions from cache:
    Context
      .getProcessEngineConfiguration()
      .getDeploymentManager()
      .removeDeployment(deploymentId, cascade);
 
    return null;
  }
}

 

CommandExecutor在啥时候初始化?

在ProcessEngineConfigurationImpl中有个init方法,里面有对于executor和intecerptor的初始化。

 

CommandExecutorImpl 这个是一个基本的实现,没有迭代的东西在里面,CommandInterceptor这个和CommmandExecutor一样的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class CommandExecutorImpl implements CommandExecutor {
 
  private final CommandConfig defaultConfig;
  private final CommandInterceptor first;
 
  public CommandExecutorImpl(CommandConfig defaultConfig, CommandInterceptor first) {
    this.defaultConfig = defaultConfig;
    this.first = first;
  }
 
  public CommandInterceptor getFirst() {
    return first;
  }
 
  @Override
  public CommandConfig getDefaultConfig() {
    return defaultConfig;
  }
 
  @Override
  public <T> T execute(Command<T> command) {
    return execute(defaultConfig, command);
  }
 
  @Override
  public <T> T execute(CommandConfig config, Command<T> command) {
    return first.execute(config, command);
  }
 
}

 

CommandInterceptor拦截类,有多个实现,这里是串接命令模式和责任链模式的衔接点

1
2
3
4
5
6
7
8
9
public interface CommandInterceptor {
 
  <T> T execute(CommandConfig config, Command<T> command);
 
  CommandInterceptor getNext();
 
  void setNext(CommandInterceptor next);
 
}

 

分享到:
评论

相关推荐

    工作流activiti源码案例

    7. 自定义扩展:Activiti允许开发人员自定义行为,如自定义任务命令(Command)、监听器、行为(Behavior)等,这些可能在案例中有所体现。 通过深入研究这些源码案例,开发者可以更好地理解和应用Activiti工作流...

    activiti源码-最新-中文注释

    2. **EngineImpl**:实际的流程引擎实现,包括了命令模式的设计,使得每个操作都通过Command对象执行,增强了系统的可扩展性和可维护性。 3. **Task**:任务管理,包括任务的创建、分配、完成等逻辑。 4. **Job...

    ActivitiSourceCode:Activiti5.22原始码中文注释,

    4&gt; Activiti优化的类Activiti四大cahce类5&gt; Activiti定时任务相关类6&gt; Activiti第二层解析PVM相关类7&gt;监听器及其相关类8&gt; Activiti核心设计模式命令类以及责任链模式9&gt; Activiti支持PVM运转的类(XXXopertaion)也...

    activiti源码

    6. **学习设计模式**: Activiti 源码中应用了许多设计模式,如工厂模式、观察者模式等,这对于提高软件设计能力很有帮助。 通过研究"activiti源码",开发者不仅可以掌握 Activiti 的工作原理,还能学习到先进的软件...

    java设计模式详解

    15. **命令模式**:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或者记录请求日志;支持可撤销的操作。 16. **责任链模式**:处理请求的对象形成一条链,请求沿链传递,直到被...

    activity源码

    2. **流程定义解析**:Activiti使用`BpmnModel`类来表示BPMN 2.0流程定义,它将XML文件解析为内存中的数据结构。`BpmnParser`类承担了这个任务,解析流程定义并构建`BpmnModel`。 3. **执行模型**:在运行时,...

    activiTest.zip

    在调用Activiti服务时,我们应确保每个调用都包裹在Hystrix命令中,以提高系统的稳定性和容错性。 最后,流程监控是不可或缺的一环。Activiti5提供了历史数据库,记录了流程实例、任务实例等运行数据。我们可以利用...

    王凯某求职简历_20201129154431_嵌入式_java简历_程序员简历模板_计算机相关专业.doc

    2. JAVA设计模式:熟悉常用的JAVA设计模式,如单例、装饰、工厂、代理等。 3. Web开发框架:熟悉Struts2、Spring、Hibernate等框架,理解Struts2核心流程、Hibernate的一二级缓存、Spring IOC、DI、AOP等。 4. ...

    JAVA上百实例源码以及开源项目源代码

    在有状态SessionBean中,用累加器,以对话状态存储起来,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean正常被激活和钝化,EJB对象是用完毕,从内存中清除…… Java Socket 聊天...

Global site tag (gtag.js) - Google Analytics