activiti命令模式与责任链模式

news/2024/5/19 14:24:44 标签: 命令模式, 责任链模式

来源:activiti学习(七)——命令模式和职责链模式在activiti中的应用

文章目录

  • 设计模式
    • 命令模式
      • Command
        • HelloCommand
        • ByeCommand
      • Receiver
      • Invoker
      • Client
    • 职责链模式
      • AbstractHandler
        • ConcreteHandlerA
        • ConcreateHandlerB
      • Client

activiti中很多api的调用,最终会把这个调用封装成一个命令,使用命令模式去调用。另外还会把命令放在调用链上,当调用该命令时会依次调用职责链上的每一个拦截器(Interceptor),例如日志、事务相关拦截器,然后调用指定的命令。本章先对这两种设计模式进行介绍

设计模式

命令模式

命令模式其作用是为了对 “行为请求者” 和 “行为实现者” 这两者进行解耦。下图是命令模式的UML图。
在这里插入图片描述

其中

  • HelloCommand和ByeCommand是具体命令,
  • Receiver是命令的实际执行者。
  • Invoker是提供给客户端进行调用的类。

Command

public interface Command {
	void execute();
}
HelloCommand
public class HelloCommand implements Command {
 
	private Receiver receiver = null;
	
	public HelloCommand(Receiver receiver) {
		super();
		this.receiver = receiver;
	}
 
	public void execute() {
		receiver.helloAction();
	}
}
ByeCommand
public class ByeCommand implements Command {
 
	private Receiver receiver = null;
	
	public ByeCommand(Receiver receiver) {
		super();
		this.receiver = receiver;
	}
 
	public void execute() {
		receiver.byeAction();
	}
}

Receiver

public class Receiver {
 
	public void helloAction() {
		System.out.println("hello");
	}
	
	public void byeAction() {
		System.out.println("good bye");
	}
}

Invoker

public class Invoker {
 
	private Command command = null;
	
	public Invoker(Command command) {
		this.command = command;
	}
	
	public void action() {
		command.execute();
	}
 
	public Command getCommand() {
		return command;
	}
 
	public void setCommand(Command command) {
		this.command = command;
	}
}

Client

public class Client {
 
	public static void main(String[] args) {
	
		// 每个command都持有1个receiver
		Receiver receiver = new Receiver();
		
		// 不同的command 都会调用receiver中的不同方法
		HelloCommand helloCommand = new HelloCommand(receiver);
		ByeCommand byeCommand = new ByeCommand(receiver);
		
		// 调用 invoker#action方法, 去触发Command#execute方法, 
		//     这样的话, 不同的command就有不同的行为,
		//     并且具体的command可以把调用交给receiver去完成, 也可以在自己内部完成(activiti属于这种)
		Invoker invoker = new Invoker(helloCommand);		
		invoker.action();
		
		invoker.setCommand(byeCommand);		
		invoker.action();
	}
}

职责链模式

责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。

下面这个职责链模式与之前认识的责任链模式有区别,之前的责任链的示例有在tomcat的FilterChain.doFilter 和 ReflectiveMethodInvocation#proceed都有,它们是将可以推动链条往下走的对象作为方法参数传给了链条中的每个节点,并且每个节点是感知不到下一个节点的,而下面这种每个节点能知道下一个节点的
在这里插入图片描述

AbstractHandler

AbstractHandler 预示着每个节点都维护了下1个节点,并且在自己调用完后,触发对下1个节点的调用,类似于单向链表的存在

public abstract class AbstractHandler {
 
	AbstractHandler next = null;
 
	public void setNext(AbstractHandler next) {
		this.next = next;
	}
	
	public void handle() {
		action();
		if(next != null) {
			next.handle();
		}
	}
 
	public abstract void action();
}
ConcreteHandlerA
public class ConcreteHandlerA extends AbstractHandler{
 
	public void action() {
		System.out.println("handle A");
	}
}
ConcreateHandlerB
public class ConcreteHandlerB extends AbstractHandler{
 
	public void action() {
		System.out.println("handle B");
	}
}

Client

public class Client {
	
	public static AbstractHandler initChain() {
	
		// 创建2个节点
		ConcreteHandlerA concreteHandlerA = new ConcreteHandlerA();
		ConcreteHandlerB concreteHandlerB = new ConcreteHandlerB();
		
		// A节点的下一个节点是B节点
		concreteHandlerA.setNext(concreteHandlerB);
		
		return concreteHandlerA;
	}
 
	public static void main(String[] args) {
	
		AbstractHandler handlerChain = initChain();

		// 触发A节点的调用, A调用完成之后, 触发对B节点的调用
		handlerChain.handle();
	}
}

http://www.niftyadmin.cn/n/5171410.html

相关文章

NO.304 二维区域和检索 - 矩阵不可变

题目 给定一个二维矩阵 matrix,以下类型的多个请求: 计算其子矩形范围内元素的总和,该子矩阵的 左上角 为 (row1, col1) ,右下角 为 (row2, col2) 。 实现 NumMatrix 类: NumMatrix(int[][] matrix) 给定整数矩阵 …

小程序样式问题

小程序切换下一个文章或者页面,淡入淡出效果 // detail.js getArticleData: function(articleId) {// 开始淡出效果this.animate(.detail-page, [{ opacity: 1.0, ease: ease-out },{ opacity: 0.0, ease: ease-out }], 500, () > {// 在淡出动画完成后请求文章…

openstack部署后实战

分布式部署规则 1、平常都是两台Node安装OpenStack平台,那如果想分布式部署该怎么做?比如:部署两台Nova服务,一台单独的Neutron服务,一台单独的存储节点等。 整体思想: 如果想要部署两台Nova服务&#xf…

【分布式】tensorflow 1 分布式代码实战与说明;单个节点上运行 2 个分布式worker工作线程

tensorflow.python.framework.errors_impl.UnknowError: Could not start gRPC server 1. tf分布式 一台电脑服务器server是一个节点,包含了多个GPU。首先分布式的方式就是让多台电脑上的gpu共同干活。 分布式工作分为两个部分,parameter server&#…

leetCode 493 翻转对

给定一个数组 nums &#xff0c;如果 i < j 且 nums[i] > 2*nums[j] 我们就将 (i, j) 称作一个重要翻转对。你需要返回给定数组中的重要翻转对的数量。 未完待续~

WPS数组

一、创建数组方法和数组的读取、修改、写入 数组是值的有序集合&#xff0c;其中的值叫作元素。每个元素有一个数值表示的位置&#xff0c;叫作索引&#xff0c;数组中的不同元素可以是不同数据类型。 function demo(){var arr1[99,"人","abc",[3,4,5]];…

推导式与生成器

实验目的‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬ 掌握推导式与生成器的概念与应用方法‪‬‪‬‪‬‪‬‪‬…

5-7 使用函数求余弦函数的近似

实现一个函数&#xff0c;用下列公式求cos(x)的近似值&#xff0c;精确到最后一项的绝对值小于e&#xff1a;‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬…