还在 Show me the code?Show xUnit 了!
面对现实
编程之神(Linus)曾经说过:talk is cheap, show me the code.
年轻时我也很吃这一套,说这话时仿佛自己就是大神本神。但被生活的波澜无情的拍打了这么多年后,今天的我只想说:你那 shit 一般的代码,有多远拿远吧,拜托了。毕竟我连自己半年前写的代码都不想看,还指望我看你的代码?
作为一个 24K 老后端研发,为什么我讨厌看代码呢?因为很多人眼里以为后端研发是这样的:
但是实际上后端研发更像这样:
看这无辜的小眼神,是的,本质上我们的工作没有两样。
理想的世界里,我们有需求文档,有设计图,有良好的程序结构,完美的注释和 bug free 的代码。但在现实中,你面对的可能是个 N 手系统,你是第 N+1 个倒霉鬼,当年细皮嫩肉的需求文档早就找不到了,系统现在的结构和之前的设计比较起来只是略有相似而已(如果还能找到设计的话),而代码就像一个被重拳反复捶打过的烂泥堆一样,唯一靠得住的注释大概就只有前几任作者的名字。。。
每当出现线上问题时,我们就要深吸一口气,回望一眼这美好的世界,然后鼓起 12 分的勇气跳到无尽的迷(fen)宫(keng)中。很多时候我们既不知道问题在哪,我们也不知道自己在哪。比起找到是谁的问题,我们更希望证明不是自己的问题。运气好时,我们很快就能冒头,但当运气不那么好时,我们要在坑里待多久就只有天知道。每当这个时候我就忍不住在想:有没有一个办法,让我们不看代码也能清楚的知道系统结构,能快速的定位到可疑的模块?
问题与答案
在很多个独自加班的夜里,我这么想着。看着市面上各种技术手段,编程方法与设计思想来来去去,终于明白救世主不会来,还得靠自己。于是就有了 xunit,一个能用流程图表达系统处理结构的可视化低代码工具。它长下面这样:
这张图的含义是:
这是一个运行在 IDE 里的可视化开发工具
它用流程图表示业务逻辑,支持顺序,选择,循环,嵌套和并发等结构
每个节点对应一个处理单元,你需要绑定代码,因此这不是一个给小孩子玩的图形化编程工具
它意味着什么:
你不用一行行看代码就能清晰的知道整个业务的逻辑结构
流程图已经定义了处理顺序,你只需像做填空题一样用最少的代码去实现真正核心的逻辑
从模型可以直接跳转到代码。你随时可以从抽象结构层面进入到具体的代码层面,普通的设计文档永远无法做到这点
它描述的是后端逻辑,不是前端页面。谢天谢地,终于有人明白无论多牛的页面编辑器都不可能实现哪怕一丁点后端逻辑
它集成在 IDE 里。你不必担心 IDE 和设计工具之间的切换会打断程序员最宝贵的心流
设计和运行使用同一个模型。永远不会出现设计文档和实际系统不一致的问题
没有代码生成这种额外步骤,系统不会因为用了它而增加一堆既看不懂,也无法维护的东西
这难道不是作为后端研发的你一直梦寐以求的工具吗?xunit 同时支持 IDEA 和 Eclipse,下面以 IDEA 为例,介绍其安装使用过程。
接下来的 5 分钟,将为你打开一个新世界。
安装插件
在 IDEA 里面通过 File->Settings->Plugins->Brows Repository 打开插件仓库界面。 输入 xross 可以看到 X-Series 系列插件。选择 Xross Unit Editor 进行安装,重启 IDEA 即可
创建模型
通过 File->New->Xross Uint Model 打开对话框,输入模型名称后将在 resources 目录创建.xunit 结尾的模型文件
我们的需求是创建一个字符串处理的业务逻辑:首先对请求中的字符串变量进行预处理,增加一个前缀,其次判断处理后的变量长度,如果大于 10,则将该字符串转为大写。需求本身很简单,但可以完整的展示利用 xunit 创建系统的过程。
首先单击左侧工具栏的 Processor 按钮,再单击中间主窗口空白处放置我们的第一个单元。
接下来再单击 Processor 按钮,然后单击刚才创建的单元,我们就得到了顺序执行的两个单元:
最后单击 Validator 按钮,再单击第二个 processor,得到一个分支结构:
点击各个节点,在属性窗口中将第一个名字改为 Check input,第二个改为 To upper case,整个流程改为 demo proces。到此模型创建工作就完成了。
到此为止,我们没有写一行代码,但我们有了一个简单的逻辑结构,我们的设计工作就完成了,是不是非常便捷直观?
因为有缺省实现,现在 demo process 已经是一个可调用的模块,但不会有什么用处,接下来让我们干点老本行。
编写代码
引入依赖
xunit 已经发布到 maven 中央仓库,POM 里面增加如下配置即可:
数据定义
任何的业务流程做的都是数据处理,在 xunit 中数据用空接口 Context 表示,我们首先来定义一个包含 String 成员变量的 Context:
处理定义
流程图的节点表示对 Context 进行处理。xunit 中定义了几种处理方式,比如对 Context 的成员变量进行处理,将一个 Context 转换为另一个 Context,对 Context 进行对错判断等等。最基本的就是对成员变量进行处理,xunit 中用 Processor 接口表示。
我们对 Check input 节点的实现如下,如果是空字符串则置为“-/-”,然后增加“Text:”前缀:
xunit 用 Validator 接口表示判断处理实现。我们实现一个当字符串长度超过 10 时返回 true 的判断:
最后是将字符串全部变为大写,同样也是实现 Processor 接口:
绑定实现
为了将流程图中的各个节点和实现绑定,我们可以右键单击某个节点,选择 Assign implementation class
然后输入类名即可:
其他几个节点也依葫芦画瓢就行。
调用模型
画图的目的是为了调用,调用的方式很简单,提供模型文件的名字和处理流程的名字就行。根据逻辑我们测试 3 个 case。
输入空字符串
输入一个加前缀后长度不超过 10 的字符串
输入一个加前缀后长度超过 10 的字符串:
接下来是见证奇迹的时刻了:
可以看到结果完美符合预期。输入为空时,增加前缀后长度小于 10,不会做转大写的操作;输入非空,增加前缀后长度也小于 10,同样不会做转大写的操作;只有当增加前缀后长度大于 10,才做转大写的操作。
xunit 优势
上面只是牛刀小试,但已经足够展示 xunit 的能力。用 xunit 之后,你会发现之前靠人的努力自觉和流程规范强制的做法是非常低效的。
借助 xunit,你可以在一分钟内完成设计,并且设计模型和实际系统永远保持一致。跟人讲解系统时再也不用尴尬异常的 show me the code!只要把 xunit 模型打开,一切都一目了然。维护系统时也不用再靠人肉对代码的熟悉。即便需要看代码,双击节点就能打开编辑器。
你以为 xunit 的能力就这些吗?这只是常规操作,关注我,接下来的分享中我将展示真正的技术。
参考资料
在低代码工具选项难题浅析里,我对后端研发觉得低代码工具不好使的原因做了探讨。
在再要扯皮,就上Xstate里,我介绍了用状态机表达复杂业务状态,并解决沟通难题的办法。
xunit,xstate 和 xdecision 同属于开源低代码框架X-Series的一部分。关于 xdecision,我会单独介绍。下面是其他一些资料:
如果对 X-Series 感兴趣,欢迎加入技术支持群:
评论