• 可扩展流程设计工具方案


      本文阐述了基于元数据和xml的流程设计工具的一种实现方案,目的是能够让流程设计工具以最小的变动来应对不同项目、不同业务场景的需求变化。

      首先,我们来看一种比较常见的设计工具的结构:

     

      上面仅是设计工具部分,该部分只是生成用户建模流程的xml,至于后台解析部分该模型就不详细介绍了。

      流程图形设计工具是系统与用户进行交互的部分,用户在此设计流程的流转过程,定义运转过程的变量,设置流程各个环节的相关属性。模型视图转换器负责将流程图形设计工具接收到的图形对象和流程对象分别转换成流程流转设计图和流程对象设置视图(相当于属性设置窗口);该转换器同时负责将对象的属性变化更新到相应的对象中。

      流程图形、模型定义转换负责两部分的内容,一是将流程图形设计工具中的图形对象、流程对象以及他们之间的关系转换成流程定义模型(例如xpdl等);二是将流程定义模型解析转换成图形对象、流程对象。该部分是模型与UI交互的桥梁。

      图形对象模型定义了用户所能使用的活动类型的界面展示信息,包括坐标、运转信息(路径)、图标、高度宽度等内容。

      流程对象模型定义了流程、活动等的属性信息。

      在该实现结构中,无论是流程定制工具的实现、流程模型定义xml的解析、持久化过程都是流程设计工具开发人员来做的,一般来说,该结构能够处理业务相对固定,个性化属性内容比较少的流程模型。但是对于项目业务领域跨度相对较宽,各个项目上流程个性化属性相对较多的情况,该结构就不能满足需求了。如果继续使用上面结构,那么势必需要对流程对象模型的层次结构做出改变,纵向增加类继承层次,横向增加流程、活动类型扩展;相应的,基础业务模型变化后,图形模型也要改变,转换器需要对应的增加,后台xml解析逻辑也要发生变化……

      我们可以通过下面的例子来说明以下过程:

        1.A项目有人工活动,该活动有活动名称、活动类型、活动执行人、活动预警这些属性;我们给该活动建立流程模型:

        class ProjectAActivity
        {
            public string Name { getset; }
            public string Type { getset; }
            public string Executor { getset; }
            public string Warn { getset; }
        }

        同时建立该类型的图形对象模型:

        class ProjectAActivityNode
        {
            public int X { getset; }
            public int Y { getset; }
            public ProjectAActivityNode PreviousNode { getset; }
            public ProjectAActivityNode NextNode { getset; }
        }

        我们还需要有一个转换器将用户设计后的图形、流程模型转换成xml,暂且定义为:ProjectAXMLConverter,还有一个后台解析类ProjectAXMLParser。至此,满足该需求的设计工具基本结构出来了。

       2. 项目组接到一个新项目,要求人工活动能够设置延迟时间,以及监控者………

    class ProjectAActivity
        {
            public string Name { getset; }
            public string Type { getset; }
            public string Executor { getset; }
            public string Warn { getset; }
            public DateTime DelayTime { getset; }
        }

    ProjectBXMLConverter、ProjectBXMLParser..........
    3.项目组又一次中标,但是客户说人工活动可能是外部勘察还击,到达此类型环节时流程计时停止,等勘察完毕激活后才可继续执行 

    class ProjectAActivity
        {
            public string Name { getset; }
            public string Type { getset; }
            public string Executor { getset; }
            public string Warn { getset; }
            public bool IsExternal { getset; }
        }

    ProjectCXMLConverter、ProjectCXMLParser..........
    4. ……… 

      面对这种情况,我们怎么办?针对每个项目我们做一个分支版本,那么在重构、性能优化、测试维护上,我们将要面临越来越大的麻烦,随着项目的增多,工作量增加,你将越来越难以从繁重的工作中走出来……;增加一个项目类型参数?根据不同的参数加载不同的模型、XMLConverter及XMLParser?随着项目的增加,设计工具代码量必然增加,各种修补逻辑,各种加载器、转换器、模型层次结构必然会引来越来越多的麻烦,维护成本慢慢增加…….

      为了应对这种复杂多变的环境,同时保持底层业务模型的相对固定,我们需要对上面的结构进行一定的改进,如图:

     

      我们分别在流程对象模型中增加了扩展模型,在设计工具部分增加扩展模型定制和扩展模型视图转换。其实这三部分的主要作用就是配置扩展属性(即个性化属性);定义扩展属性生成xml和从xml中解析的规则;定义扩展属性在UI中显示的规则。

      对于扩展属性的配置,实现起来相对简单,类似于下面的一个UI界面即可搞定:

     

      当然,实际配置界面可能比这个要麻烦的多,要根据不同的类型显示不同的配置界面,同时对于属性值的校验规则,全局唯一标识符的有效性等都要进行一定的处理。

    定制完成之后,当我们在设计工具中新增某类型的环节时,模型视图转换器在解析完固定模型之后,会读取该类型活动的扩展信息,同时根据扩展属性的类型,生成对应的视图对象显示到视图容器中。对于属性的变化,通过事件定制及时的反映到对应的属性中。流程对象模型扩展则负责定义将扩展属性转换成xml的规则,以及将xml解析成具体模型对象的逻辑。

      对于用户扩展的属性,前台生成相关xml后台又如何处理呢?答案是定义扩展属性输出接口,将流程模型中所有的扩展属性以一定的格式交给这个接口的实现来处理。这种情况下最多是多写个处理类,然后针对项目配置一下,如果用户是二次开发人员,那甚至设计工具开发者都不需要做什么工作。

      通过这种改变,我们可以摆脱扩展、维护、扩展、维护…..的噩梦,摆脱维护多个版本或者维护复杂层次模型的工作,将主要的精力放在提供更多的配置项,提高工具的扩展性,易用性,健壮性上。

  • 相关阅读:
    算法-对分查找(二分查找)C++实现
    Android Studio简单设置
    一起talk C栗子吧(第八回:C语言实例--素数)
    Maven生命周期
    java8_api_日期时间
    UITableviewcell的性能问题
    iOS开发25个性能调优技巧
    iOS9新特性
    iOS9 3DTouch、ShortcutItem、Peek And Pop技术一览
    iOS网络访问之使用AFNetworking
  • 原文地址:https://www.cnblogs.com/jingtao/p/1800899.html
Copyright © 2020-2023  润新知