activiti和设计模式(3)

提到activiti的核心业务的组织方式,就不得不提到,BPMN规范中各个图形代表的意义,各个参数的设置等等纷杂的问题。 中间我们关注的是activiti对bpmn规范中各个图形对应的对象组织方式,以及其中的设计模式。更准确的说是继承,扩展和组合的使用定义。

首先是:流程定义的解析,我们可以知道总体的模型对应的类是:BpmnModel,但是这个模式是怎么得到的?

BpmnXMLConverter converter = new BpmnXMLConverter();

bpmnModel = converter.convertToBpmnModel(streamSource, validateSchema, enableSafeBpmnXml, encoding);
//使用fasterxml 来解析xml
if (ELEMENT_DEFINITIONS.equals(xtr.getLocalName())) {
    definitionsParser.parse(xtr, model);
} else if (ELEMENT_RESOURCE.equals(xtr.getLocalName())) {
resourceParser.parse(xtr, model);
} else if (ELEMENT_SIGNAL.equals(xtr.getLocalName())) {
signalParser.parse(xtr, model);
} else if (ELEMENT_MESSAGE.equals(xtr.getLocalName())) {
          messageParser.parse(xtr, model);
}

//具体针对各个BPMN规范的解析
protected BpmnEdgeParser bpmnEdgeParser = new BpmnEdgeParser();
protected BpmnShapeParser bpmnShapeParser = new BpmnShapeParser();
protected DefinitionsParser definitionsParser = new DefinitionsParser();
protected DocumentationParser documentationParser = new DocumentationParser();
protected ExtensionElementsParser extensionElementsParser = new ExtensionElementsParser();
protected ImportParser importParser = new ImportParser();
protected InterfaceParser interfaceParser = new InterfaceParser();
protected ItemDefinitionParser itemDefinitionParser = new ItemDefinitionParser();
protected IOSpecificationParser ioSpecificationParser = new IOSpecificationParser();
protected DataStoreParser dataStoreParser = new DataStoreParser();
protected LaneParser laneParser = new LaneParser();
protected MessageParser messageParser = new MessageParser();
protected MessageFlowParser messageFlowParser = new MessageFlowParser();
protected MultiInstanceParser multiInstanceParser = new MultiInstanceParser();
protected ParticipantParser participantParser = new ParticipantParser();
protected PotentialStarterParser potentialStarterParser = new PotentialStarterParser();
protected ProcessParser processParser = new ProcessParser();
protected ResourceParser resourceParser = new ResourceParser();
protected SignalParser signalParser = new SignalParser();
protected SubProcessParser subProcessParser = new SubProcessParser();

我们最后看一下,BpmnModel的组成:

	protected Map<String, List<ExtensionAttribute>> definitionsAttributes =
new LinkedHashMap\<String, List<ExtensionAttribute>\>();
	protected List<Process> processes = new ArrayList<Process>();
	protected Map<String, GraphicInfo> locationMap = new LinkedHashMap<String, GraphicInfo>();
	protected Map<String, GraphicInfo> labelLocationMap = new LinkedHashMap<String, GraphicInfo>();
	protected Map<String, List<GraphicInfo>> flowLocationMap = new LinkedHashMap<String, List<GraphicInfo>>();
	protected List<Signal> signals = new ArrayList<Signal>();
	protected Map<String, MessageFlow> messageFlowMap = new LinkedHashMap<String, MessageFlow>();
	protected Map<String, Message> messageMap = new LinkedHashMap<String, Message>();
	protected Map<String, String> errorMap = new LinkedHashMap<String, String>();
	protected Map<String, ItemDefinition> itemDefinitionMap = new LinkedHashMap<String, ItemDefinition>();
	protected Map<String, DataStore> dataStoreMap = new LinkedHashMap<String, DataStore>();
	protected List<Pool> pools = new ArrayList<Pool>();
	protected List<Import> imports = new ArrayList<Import>();
	protected List<Interface> interfaces = new ArrayList<Interface>();
	protected List<Artifact> globalArtifacts = new ArrayList<Artifact>();
	protected List<Resource> resources = new ArrayList<Resource>();
	protected Map<String, String> namespaceMap = new LinkedHashMap<String, String>();
	protected String targetNamespace;
	protected List<String> userTaskFormTypes;
	protected List<String> startEventFormTypes;
	protected int nextFlowIdCounter = 1;

你会发现,在调试的时候老出现的Activity之类的并没有出现,那么BpmnModel和ProcessDefinitionImpl是怎么关联起来的呢?同样是在BpmnParse中,可以发现:

public BpmnParse execute() {
  。。。。。。
// Validation successfull (or no validation)
createImports();
createItemDefinitions();
createMessages();
createOperations();
transformProcessDefinitions();
  。。。。。。
}

具体的操作是在:org.activiti.engine.impl.bpmn.parser.BpmnParse.processDI()中,主要的代码是:

  // Parse diagram interchange information
        ProcessDefinitionEntity processDefinition = getProcessDefinition(process.getId());
        if (processDefinition != null) {
          processDefinition.setGraphicalNotationDefined(true);
          for (String shapeId : bpmnModel.getLocationMap().keySet()) {
            if (processDefinition.findActivity(shapeId) != null) {
              createBPMNShape(shapeId, bpmnModel.getGraphicInfo(shapeId), processDefinition);
            }
          }

          for (String edgeId : bpmnModel.getFlowLocationMap().keySet()) {
            if (bpmnModel.getFlowElement(edgeId) != null) {
              createBPMNEdge(edgeId, bpmnModel.getFlowLocationGraphicInfo(edgeId));
            }
          }

从这里我们可以看出来:BpmnModel只要支持的Bpmn的规范,支持的是xml中定义的各个图形的对象,以及对象的属性。ProcessDefinitionEntity主要的是流程运转的过程中的对象,这点从类的命名上面也可以看出来。

这里想说的是设计模式:组合模式(Composite pattern),以及解析过程中的工程模式(Abstract factory pattern)。

组合模式:

首先是每一个元素都会含有实行,在activiti中属性抽象为一个接口,
所有的基础元素都会实现该接口:			
org.activiti.bpmn.model.HasExtensionAttribute     

public abstract class BaseElement implements HasExtensionAttributes
public abstract class FlowElement extends BaseElement implements HasExecutionListeners

BaseElement 被设计为抽象的类型,这个感觉基础元素,不会出现在xml定义中,也就符合了抽象类:不能被实例化的特性。

BaseElement的继承的体系,如附件所示:

其中我们比较属性的Usertask,Process的集成体系也如附件中体现:

baseElement的集成体系 flowElement继承体系

单独的把FlowElement列出来,是因为抽象类FlowElement中有一个比较好玩的,也是比较重要的方法: public abstract FlowElement clone();

可以直接的克隆一个元素出来,在后期的扩展中,这个是比较有用的一个方法,在继承体系,所有的元素都实现了这个方法,也就为了后面的扩展提供了基础。

上面的BpmnModel就是典型的组合模式,但是在继承体系中,也是含有组合的,最容易理解的莫过于子流程的定义了,即:

public class SubProcess extends Activity implements FlowElementsContainer {
  protected List<FlowElement> flowElementList = new ArrayList<FlowElement>();
  protected List<Artifact> artifactList = new ArrayList<Artifact>();
  protected List<ValuedDataObject> dataObjects = new ArrayList<ValuedDataObject>();

在BPMN的解析的过程中,使用到了抽象工厂的类:

public interface BpmnParseFactory {
  BpmnParse createBpmnParse(BpmnParser bpmnParser);
}   

默认的工程类:

public class DefaultBpmnParseFactory implements BpmnParseFactory {

  public BpmnParse createBpmnParse(BpmnParser bpmnParser) {
    return new BpmnParse(bpmnParser);
  }
}

使用的情况:

if (bpmnParseFactory == null) {
      bpmnParseFactory = new DefaultBpmnParseFactory();
    }

个人感觉有点过度设计的感觉,但是为了扩展,也是无可厚非。

Powered by andiHappy and Theme by AndiHappy