`

FoxBPM 系列之-设计模式、OO原则

阅读更多
时光荏苒,不忘初心,勿在浮沙筑高台!继续每周一篇的FoxBPM 系列!
流程引擎永远不可能独立的面向客户,它必须通过组建的方式集成于平台和客户交互。既然是组件那么我们就需要将其架构设计的具有弹性、可重用性、平台关联性、和其他组件的互联互通性等等。那么什么样的架构才能达到这样的高度?什么样的设计才能满足这样的要求?凡此种种。本周就带着这些疑问跟大家介绍一下FoxBPM流程引擎的架构设计中所遵循的OO原则和运用的设计模式。
 
首先看一下整个流程引擎设计所遵循的一些OO原则:
1、单一职责原则
     FoxBPM引擎的外层service具体实现都由Command命令封装之,和ACTIVITI相似,Command设计模式的引入将流程运转中的功能进行模块化粒度化,职责单一化。每个模块只负责其中一件事,这样系统进行功能扩展时就更加容易,解耦的更加彻底。我们生活中也是如此,如果专心做一件事,这件事肯定能做的很好。正所谓“样样精通,样样稀松”就是这个道理。整个系统的功能扩展都得益于这样的模块化设计。
 
2、接口隔离原则
     整个流程的运转是基于一个引擎虚拟机的,而虚拟机的运行基于令牌算法(我们系统的微内核由令牌驱动,和JBPM类似,不知道令牌算法的请看Petri Net网,百度之。可以说Petri Net是很多流程语言的父亲),所以令牌算法模块结构设计的优良与否直接影响到整个流程的运转。由于令牌支撑的是整个流程引擎,所以令牌需要面对不同的客户不同的功能模块,比如说事件监听执行、节点跳转、引擎表达式执行等等,针对这些问题流程引擎设计了多个不同的接口代表令牌所要演示的角色,将令牌的功能宽窄化。这样令牌就可以将其自身的职责功能发挥的尽善尽美了!
 
3、开闭原则
    开闭原则属于几大原则中最高级最抽象的原则,只可意会不可言传!美其名曰:“对变更关闭、对扩展开放”。人类在进步,市场在变化,客户的需求也无时无刻不在变化,为了达到快速响应的目的,这就要求我们将程序设计的更容易扩展。虽然工作流领域相对稳定,但是我们FoxBPM引擎架构设计时依然遵循这样的高级原则。比如BPMN模型解析转换模块、流程引擎装配模块,基于该原则的设计下,我们就可以很容易的添加新的模型的转换,也可以轻而易举的将Spring事物管理集成进流程引擎。遵循了这个原则,流程引擎和spring的集成、和其他组件的集成也就顺理成章了。
 
4、依赖倒置原则
      该原则应该是OO最核心的原则,也是我们流程引擎完全遵循的原则。其大致概念为:一切依赖于抽象,一切面向接口变成,所有的细节全部依赖于抽象,不允许抽象依赖于具体实现,所有的客户端全部依赖于抽象耦合。FoxBPM流程引擎整体架构设计时全部遵循该原则,但具体功能模块实现时存在个别缺陷,并没有彻底的遵循该原则。依然存在:继承具体类的、变量指向具体类的引用、子类方法重写父类中已经实现的方法等等情况,其实某些相对稳定的很难再变化的模块存在这些情况也无可厚非。带有过程色彩的引擎架构,在该原则下同样富有弹性、可重用性、所有抽象和细节彼此隔离。
 
 
FoxBPM流程引擎都是怎么遵循这些原则的?都是通过哪些方式来遵循的?
好,守得云开见月明!带着这些疑问我们继续来看系统架构设计时所运用的一些设计模式。其实架构设计时设计模式很好的运用就是遵循OO原则的最好体现。比如说命令模式把发出命令的责任和执行命令的责任分割开,委派给不同的对象,解耦的同时也体现了模块设计遵循单一职责原则;比如说装饰者设计模式,动态添加对象的功能,也体现了开闭原则;构建模式在将一个复杂的构建与其表示相分离的时候也体现了依赖倒置原则等等。
 
1、Command设计模式和责任链设计模式
印象最深的是Command设计模式,FoxBPM流程引擎的上层接口,每一个功都封装为一个命令然后交给一个责任链去处理,责任链处理过程包括:创建命令环境、设置流程引擎配置环境、启动事物、记录请求参数、执行命令、持久化缓存、清空表达式引擎环境、清空命令环境、清空流程引擎环境。
   相关代码模块如下所示:
  
 
    cmd定义模块如下图:
   
 
 CommandContextInterceptor负责命令执行之前环境初始化,LogInterceptor负责命令执行的日志记录,SpringTransactionInterceptor负责事物管理、CommandInvoker负责最终任务的执行。
 
2、观察者设计模式 
前段时间做了一个运行轨迹监听器,该功能负责监听记录流程运行过程中产生的轨迹包括任务节点进入、执行、离开,线条网关的执行。该模块相对独立,实现的也很容易,都是得益于该设计。流程运转中连接器的执行也是基于该设计模式。
   我们可以在虚拟机里面看节点容器类KernelFlowElementsContainerImpl里面包含了一个监听器的定义,目前监听的注册包括两个模块,一个是由BPMN模型转化到虚拟机模型时注册、一个是用户自己扩展的监听器注册。
    代码如以下所示:
public class KernelFlowElementsContainerImpl extends KernelFlowElementImpl
		implements
			KernelFlowElementsContainer { 
	protected List<KernelFlowNodeImpl> flowNodes = new ArrayList<KernelFlowNodeImpl>();
	protected Map<String, KernelFlowNodeImpl> namedFlowNodes = new HashMap<String, KernelFlowNodeImpl>();
	protected Map<String, KernelSequenceFlowImpl> sequenceFlows = new HashMap<String, KernelSequenceFlowImpl>();

	protected List<KernelLaneSet> laneSets = new ArrayList<KernelLaneSet>();
	protected List<KernelArtifact> artifacts = new ArrayList<KernelArtifact>();
	protected Map<String, List<KernelListener>> kernelListeners = new HashMap<String, List<KernelListener>>();
   
   相关事件执行代码如下:
public void execute(InterpretableExecutionContext executionContext) {
		KernelFlowElementsContainerImpl container = getContainer(executionContext);		
		String eventName = getEventName();
		List<KernelListener> kernelListeners = container.getKernelListeners(eventName);
		int kernelListenerIndex = executionContext.getKernelListenerIndex();
		if (kernelListeners.size() > kernelListenerIndex) {
			executionContext.setEventName(eventName);
			executionContext.setEventSource(container);
			KernelListener listener = kernelListeners.get(kernelListenerIndex);
			try {
				listener.notify(executionContext);
			} catch (RuntimeException e) {
				throw e;
			} catch (Exception e) {
				throw new KernelException("不能执行事件监听 : " + e.getMessage(), e);
			}
			executionContext.setKernelListenerIndex(kernelListenerIndex + 1);
			executionContext.fireEvent(this);

		} 
	}
   
基于监听器的设计,目前已经扩展的功能包括流程实例启动结束的监听、流程运行轨迹的监听、流程运转中连接器(包括邮件、数据库、WEB服务等等)的执行。
   虚拟机监听器扩展如下图所示:
    
 
3、组合设计模式
FoxBPM流程引擎虚拟机的流程定义结构、以及BPMN的EMF模型都是基于组合设计模式,在针对组合设计客户端可以很好的处理解析,比如说模型解析的转换,SVG转换。       
查看SVG构造模块我们可以发现,SVG构造工厂引用的是KernelBaseElement类而不是像kernelSequenceFlowImpl、kernelAssociationImpl、KernelFlowNodeImpl等这样具体子类,这样就可以屏蔽掉差异,保证客户端操作的一致
 
   SVG客户端代码:
public abstract class AbstractFlowElementVOFactory {   
	protected String voTemplateFileName;
	protected KernelBaseElement kernelBaseElement;
 
   KernelBaseElement类的定义如下所示:
public class KernelBaseElementImpl implements KernelBaseElement, KernelDIBounds { 
	private static final long serialVersionUID = 1L;

	protected String id;
	protected String name;
	protected KernelProcessDefinitionImpl processDefinition;
	protected Map<String, Object> properties;

	// 图形信息
	protected float x = -1;
	protected float y = -1;
	protected float width = -1;
	protected float height = -1;

	public KernelBaseElementImpl(String id, KernelProcessDefinitionImpl processDefinition) {
		this.id = id;
		this.processDefinition = processDefinition;
	}
 
   树形结构如下所示:
   
 
 4、模板方法设计模式
模板方法是代码复用的一项基本的技术,在类库中尤其重要。,它遵循“抽象类应当拥有尽可能多的行为,应当拥有尽可能少的数据”的重构原则,模板设计模式应该是所有设计模式中最基础的最重要的一种。虚拟机所定义的流程实例,只能在内存中维护其运行状态,但是真实情况是我们必须将流程实例状态持久化,FoxBPM虚拟机设计时采用模板方法支持流程实例状态的持久化功能,从而构造一台真正能维护流程实例状态的虚拟机。
查看代码我们可以发现很多以下这样的代码机构,这也是最简单的模板方法。
   如下所示:
       public KernelProcessInstanceImpl getProcessInstance() {
		ensureProcessInstanceInitialized();
		return processInstance;
	}

	/** 子类需要重写这个方法 */
	protected void ensureProcessInstanceInitialized() {
		// TODO Auto-generated method stub

	}
 
5、中间者设计模式
我们开发过程中有时会遇到这样的情况,就是某两个模块存在关联关系,但是这两个模块自己却又不能直接和独立的维护他们自己的关系、这个时候我们就可以采用中间者设计模式。大家还记得“西门庆和潘金莲走到一起的故事”吗。
流程引擎中也有相关设计,比如流程转换过程中节点行为和边界事件行为的关联关系。这里是通过一个内部类来实现的,如下代码所示:
public static class BehaviorRelationMemo {
		/** 临时存储MAP */
		private Map<String, ActivityBehavior> attachActivityMap = new HashMap<String, ActivityBehavior>();
		private Map<String, List<EventBehavior>> beAttachedActivityMap = new HashMap<String, List<EventBehavior>>();
		
		/**
		 * 
		 * attachActivityAndBoundaryEventBehaviorRelation(创建Activity
		 * 和BoundaryEventBehavior之间的关联关系) void
		 * 
		 * @exception
		 * @since 1.0.0
		 */
		public void attachActivityAndBoundaryEventBehaviorRelation() {
			Set<String> keySet = beAttachedActivityMap.keySet();
			for (String activityID : keySet) {
				if (attachActivityMap.containsKey(activityID)) {
					List<EventBehavior> list = beAttachedActivityMap.get(activityID);
					for (EventBehavior behavior : list) {
						attachActivityMap.get(activityID).getBoundaryEvents().add((BoundaryEventBehavior) behavior);
					}
					
				}
			}
			this.attachActivityMap.clear();
			this.beAttachedActivityMap.clear();
		}
 
流程引擎系统架构优秀的设计还有很多很多,丰富多彩的API也有很多很多。作为FoxBPM产品发布前的一个铺垫,本文只是蜻蜓点水般的揭秘了一些FoxBPM引擎构架设计所遵循的部分典型的OO原则,和典型的设计模式。如有不足之处还望大家里多多指教!
 
 
 
 

====================================================================
声明:本文首发iteye blog,转载请注明作者信息及原文地址,谢谢


作者信息:
马恩亮(elma@wisedu.com) 

=====================================================================

  • 大小: 4.1 KB
  • 大小: 148.6 KB
  • 大小: 154.2 KB
  • 大小: 8 KB
  • 大小: 10.8 KB
分享到:
评论

相关推荐

    《Head First Java》是本完整的面向对象(object-oriented,OO)程序设计和Java的学习指导

    第一册:《Head First Java》是本完整的面向对象(object-oriented,OO)程序设计和Java的学习指导。 第二册:《HeadFirst设计模式》(中文版)共有14章,每章都介绍了几个设计模式,完整地涵盖了四人组版本全部23个设计...

    5-互评-OO之接口-DAO模式代码阅读及应用

    总结来说,"5-互评-OO之接口-DAO模式代码阅读及应用"这个主题涵盖了Java开发中的关键知识点,包括接口的概念及其在实现模块间契约中的作用,以及DAO模式在数据访问层的设计和实现。理解并熟练应用这些知识对于提升...

    OO设计原则 -- OO设计的 DIP依赖倒置原则

    ### OO设计原则 -- OO设计的 DIP依赖倒置原则 #### 概述 在软件工程领域,特别是面向对象设计中,依赖倒置原则(Dependency Inversion Principle, DIP)是六大设计原则之一,由著名软件架构师Robert C. Martin提出...

    设计模式课件大全

    设计模式07-组合模式、装饰模式 设计模式09-外观模式、享元模式 设计模式10-代理模式、结构型模式大复习 设计模式11-行为模式-责任链、命令模式 设计模式12-解释器模式 设计模式13-迭代器模式 设计模式14-中介者模式...

    2020-review-3-oo.pptx

    ### 设计模式的六大原则 - **单一职责原则**(Single Responsibility Principle, SRP):一个类应该只负责一个功能领域的职责。 - **开闭原则**(Open-Closed Principle, OCP):软件实体应该对扩展开放,对修改关闭...

    OO设计原则-里氏替换原则

    ### OO设计原则——里氏替换原则详解 #### 一、引言 面向对象设计原则(Object-Oriented Design Principles)是一套指导软件开发者如何更好地设计类、接口等面向对象元素的原则集合,旨在提高代码的可复用性、可...

    ex2-fishee82oo-submit-history.zip

    ex2-fishee82oo-submit-history.zip

    23种设计模式,OO思想

    标题和描述中提到的“23种设计模式,OO思想”,是软件工程领域的一个核心概念,尤其是对于面向对象编程(Object-Oriented Programming,简称OO)的深入理解和实践至关重要。设计模式是由Erich Gamma、Richard Helm、...

    head first 设计模式

    千万不要轻视这些OO原则,因为每个设计模式背后都包含了几个OO原则的概念。很多时候,在设计时有两难的情况,这时候我们必须回归到OO原则,以方便判断取舍。可以这么说:OO原则是我们的目标,而设计模式是我们的做法...

    设计模式入门指导

    在探讨设计模式的入门知识之前,我们需要对面向对象(Object-Oriented,OO)和面向过程(Procedure-Oriented)的编程思想有所了解。面向过程的编程是以事件为中心的,注重于具体的操作步骤,如C语言就是面向过程编程...

    Fundamentos-Programacao-OO-源码.rar

    "Fundamentos-Programacao-OO-源码.rar"是一个压缩包,其中包含了一系列关于面向对象编程基础的源码实例,旨在帮助学习者深入理解和掌握OOP的核心概念。 1. 封装:封装是面向对象编程的核心特性之一,它将数据和...

    OO中对于23种设计模式的整理

    OO 中的 23 种设计模式的整理 在面向对象编程(Object-Oriented Programming,OO)中,设计模式(Design Pattern)是指在软件设计中普遍存在的问题和解决方案的总结。OO 中的 23 种设计模式是指 GoF(Gang of Four...

    设计模式精解-GoF 23种设计模式解析附C++实现源码

    懂了设计模式,你就懂了面向对象分析和设计(OOA/D)的精要。...这也是我们软件设计所准求的,因此无论是OO中的封装、继承、多态,还是我们的设计模式的原则和实例都是在为了这两个目标努力着、贡献着。

    dev-license-CD5L3-5K9OO-U7UXV-06HLC-9RQN.zip

    标题中的"dev-license-CD5L3-5K9OO-U7UXV-06HLC-9RQN.zip"似乎是一个开发环境相关的授权文件压缩包。通常,这样的命名方式暗示了它包含了一些软件开发工具或者框架的许可证信息。"CD5L3-5K9OO-U7UXV-06HLC-9RQN"可能...

    设计模式资料汇总

    .pdf JAVA设计模式.chm 软件设计的七大原则.doc 设计之道.pdf C#设计模式分析.doc C#设计模式-微软.rar 从追MM谈Java的23种设计模式.txt 什么是OO思想.txt 探寻软件的永恒之道.txt 你还...

    侯捷-yahoo-GP/OO/C++

    侯捷还推荐了一系列书籍,旨在帮助读者更深入地理解STL和C++模板编程: - **《STL百科全书》**:全面介绍了STL的各种概念、原理和实践技巧。 - **《学理与规格》**:侧重于STL的理论基础和规范标准。 - **《前瞻与...

    OO设计原则总结

    设计原则是一系列指导软件开发的基本准则,遵循这些原则可以帮助开发者构建出更加灵活、易于维护和扩展的软件系统。这些原则旨在解决常见的软件设计问题,如耦合度高、代码重复、不易于扩展等问题。 #### 基本原则 ...

    剖析设计模式与设计原则

    在阅读“OO Principles Explained译文.pdf”时,你可能会发现作者如何用具体案例解释这些抽象概念,如何通过模式的组合来应对复杂的业务需求,以及如何通过遵循设计原则来优化系统结构。通过学习和理解这些内容,...

    Head First 设计模式(中文完整版+附书源码)part1

    千万不要轻视这些OO原则,因为每个设计模式背后都包含了几个OO原则的概念。很多时候,在设计时有两难的情况,这时候我们必须回归到OO原则,以方便判断取舍。可以这么说:OO原则是我们的目标,而设计模式是我们的做法...

Global site tag (gtag.js) - Google Analytics