组件的设计思路与状态机的结合(含源码)
导语:
组件是对数据产生影响的最小单元;
每个组件从context内抓取数据并处理,然后将数据放回context并返回一个状态;
状态机根据预先设计的流程,通过判断组件的状态决定下一步调用的组件。
一、组件的定义以及设计原则
组件(Component),组件就是对象,是对数据和方法的简单封装。我沿用了wsbcc技术框架对组件的规范,将组件称为Action。
设计组件应遵循如下原则:
1.坚持原子化最小化的原则设计组件的功能
2.合理抽象组件参数,提高复用空间
3.合理规划组件有明确含义的返回值
4.数据与组件分离
用人类语言打个比方:
筷子是一个组件,他的功能就是夹起东西,这个功能已经是最小的颗粒了,几乎无法继续拆分,适合作为组件功能存在;
筷子在发挥作用的时候需要补充一些应用场景相关的指令信息(参数),如“伸向右侧盘子,夹取物品为最上方的饺子,目的地为我嘴里”;
筷子发生作用的结果有几种情况,成功夹取物品,物品过重无法夹取,夹取过程中物品掉落;
饺子是数据,筷子是组件,两者是独立存在的,组件只有在工作的过程中才会与数据发生交集。当然,面条,咸菜都可以是筷子处理的数据。
综上:组件的实现形态就呼之欲出了,一个组件就是一个纯粹的方法类;仅拥有方法内部的局部变量,不会有全局变量;组件运行所需的参数,通过方法的参数传入;与组件交互的数据通过context对象承载,也作为方法的参数传入。
二、与状态机结合,使用xml描述组件在业务流程中发挥的作用
状态机中定义:
<step id="swich" map="0:encPwd;1:copyFieldToSession;other:opReply"/>
组件引用的定义:
<bean id="swich" class="com.base.steps.TranSwitchAction" switch="swichField"/>
两者配对存在,在step标签中,id是组件的别名,一个业务流程中相同组件可能会被使用多次(如数据库访问),通过别名定义组件的不同参数设置,可正确调用组件。同样这个别名一一对应bean标签的id属性;
bean标签中的class属性标识这个组件的实现类,没错就是java实现类,框架通过java反射机制获得组件的实例并使之工作;
bean标签中的switch属性就是自定义的部分了,这是组件的参数,不同的组件参数个数、名称不同,如参数形式较为复杂,可以通过定义bean的subNode描述参数信息;
组件的返回值是一个字符串,该例中swich组件的返回值就是context内”swich”参数的字段的取值,这个返回值的作用体现在状态机step标签的map属性中,描述该组件执行完成后不同的返回值调往不同的方向。
三、源代码说明
结合近几天的分享的内容,我将框架的核心部分抽取出来,制作了简单的demo。
我使用eclipseIDE 2025-06 (4.36.0)作为开发工具,程序包是直接将工作空间打包压缩的,解压后直接导入eclipse即可运行。
该演示程序编译环境为javase-24(程序代码对java版本要求不高,但依赖的包都是最新的,有jre版本要求),仅依赖log4j,jaxen(解析xml),mysqljdbc(后续讲解service会用到,先放这里),druid(阿里的数据源管理工具,后续用到,先放这)。
通过网盘分享的文件:SimpleDemo.zip
链接: https://pan.baidu.com/s/1i4TAWG07ty_5jS8ER9G69Q?pwd=dqd7 提取码: dqd7

src文件夹(源码)内的包说明:
com.base.controller main函数所在的包,用于运行框架,未来这里是mvc模式的c所在位置
com.base.ctrl 为框架核心代码包,包含数据容器(Context),状态机(StsMachine),组件抽象类(ActionUnitAbstract),以及流程加载工具(Action)
com.base.steps 为组件包,包含四个简单组件(演示流程均使用到了)
com.base.util 工具包,包含xml解析工具的封装,字符串工具,sha1加密算法,base64转换算法工具
lib文件夹(交流过程我把依赖包放在项目内,最终成品用maven构建)
xmfile文件夹 demo.xml演示业务流程的描述文件,此类文件将是框架成型后后端开发人员需要面对的唯一文件。
至此,这个框架似乎有点像那个样子了哦
下一篇我再介绍一下service,逐渐丰满。
一键三连,谢谢!
夜雨聆风
