人物设定:
小菜:具备基础的计算机理论知识,刚毕业参加工作,从事Java开发,对技术很有热情,凡事爱问个为什么,但是缺少项目实战经验,需要进一步培养。
老鸟:高级Java开发,在工作流方面有较多研究,在编程的过程中走过很多弯路,踩过很多坑之后,愿意把自己的经验、教训分享给大家。
小菜加入公司之后,就参与一个OA系统的请假业务的开发,业务场景如下:
请假人填报请假类型、请假天数、开始时间、请假原因后,根据请假天数,小于等于2天由本部门部门经理审批,大于2天由人事部门审批,审批拒绝后退回到填报人修改,通过后请假生效,在请假到期后,请假人及时在系统中办理销假。
小菜拿到需求后,二话不说就开始写代码了,首先定义个请假实体
ID,userId(请假人),days(请假天数),startDate(开始时间),reason(请假原因),vacationType(请假类型)
然后编写了请假申请的页面,部门经理审批、人事部门审批,办理销假的页面;一天过去了,小菜做得很有成就感,这样明天再完善,测试一下就应该差不多了。
快到下班的时候,小菜很自信的通过svn提交了自己的代码,看来今天不用加班了。这时老鸟从小菜身旁走过,问了下小菜今天的工作,小菜说今天做了个请假流程,定义了实体,编写了页面,完成基本的CURD操作,明天再努力一把,争取做完。老鸟笑道:小伙子效率挺高的吗,让我看看你的代码。小菜拿过自己电脑,熟练的打开了intellij,黑色的主题色立马让桌面显得高达上。老鸟看着代码,脸上的笑容慢慢收敛,眉头紧锁,程序员特有专注的表情在他脸上蔓延。旁边的小菜也跟着认真紧张起来。
5分钟后,老鸟转向小菜,问道
- 请假人能随时修改请假信息吗?比如我请假2天,请假审批通过后,我能改成10天吗?
- 怎么确定是由部门经理审批、还是人事部门审批?
- 部门经理、人事部如何获取待办?
- 审批人拒绝后请假人怎么修改?
一连串的问题,问的小菜有点不知所措,果然不愧是老鸟,一下子就问到问题的关键。小菜略微尴尬的回答:“这个问题我还没想好,我打算明天边做边想,不过我……”。“你最好要改掉边做边想的毛病”,不等小菜说完,老鸟打断了他,“编程需要抽象性思维、全局性思维,当你拿到一个需求或者碰到一个问题的时候,首先是要进行充分的思考,理解问题的本质,而不是仓促的动手,仓促编程的结果是设计缺少完整性和连贯性,后期会面临大概率的返工,还有编程不是代码越多越好,也不是越快越好,而是又快又好,编程就像写作,不只是自己看懂,也要让别人看懂,你的代码还有很多可以精简的地方”。小菜认真地听着,很肯定地“嗯”了一声,若有所思的点点头,心里想到,要是拿到需求的时候能请教下老鸟就好了。
“你刚才说,不过什么”,老鸟接着问道。“不过我刚想到一个解决办法,就是在请假实体上新增一个字段state,用于标识不同流程状态,然后根据不同的状态,限制表单是不是可以编辑”,说完,小菜拿起笔在纸上写了起来。
0=草稿状态;填报人可编辑,可提交
1=审批中;部门经理审批,填报人只读
2=审批中;人事部门审批,填报人只读
3=审批退回;填报人可编辑,可提交
4=审批结束;填报人只读
小菜写完后,看了看老鸟,他的表情不像先前那么严肃,仿佛示意他说下去,小菜接着说道:“在获取待办的时候,可以根据不同的状态来识别是部门经理的待办还是人事部门的待办”,
“那填报人的销假待办呢,如果现在需求变了,大于2天小于10天的请假依然由人事部门审批,但是大于10天的请假人事部门审批后,还需要总经理审批,该如何处理?”老鸟问道。
小菜又陷入沉思,看着那张纸,突然灵光一闪,拿起来在原来的那张纸又画了起来:
0=草稿状态;填报人可编辑,可提交
10=审批中;部门经理审批,填报人只读
20=审批中;人事部门审批,填报人只读
30=审批中;总经理审批(大于10天),填报人只读
40=审批退回;填报人可编辑,可提交
50=销假;填报人销假
60=审批结束;填报人只读
“加大状态码之间的间隔,这样随时便于插入新的节点,可以应对流程的变化”,小菜自豪地说道。
“这确实是一种解决流程问题的思路,很多业务在相对固定的业务流程中使用状态标识的方式来做流程,但是在一些流程频繁变化的业务中,这样的处理方法却不合适,这里面会存在一些问题,你能说说吗?”
刚才在纸上写的时候,小菜已经意识到这样做似乎有些不妥,正好借着这个问题,他说道:“最大的问题是,业务流程变化总导致代码的修改,还有就是,多一个节点就要多做一个界面,界面相似,却要通过Ctrl+C,Ctrl+V来操作”。
“重要的两点都说对了,你说的核心关键字是解耦
和复用
,如何保证流程能够随需应变,面对需求的变化,尽量少地去修改代码,通过业务和流程尽可能地解耦,来达到代码尽量地复用,这是流程需要重点考虑的问题。”老鸟果然是老鸟,侃侃而谈,专业术语一个个蹦出来。
“业务表单在多个环节处理流转,从而使得业务得到自动化处理,这就是工作流,其实类似的流程处理都可以用工作流来处理”,老鸟说道。
工作流?这个概念小菜还是第一次听到,恨不得立马百度一番,看看到底是个什么东西?
“交给你一个任务,晚上查查工作流的概念,建议用工作流把重新做一遍,会比现在要好多,我以前刚做类似业务的时候,和你一样,也是用状态标记业务状态,到后来状态越来越多,程序内部变得越来越臃肿,难以维护”,老鸟说着,仿佛从小菜的身上看到了当年的影子。
“但是我今天写了一天,重写的话怪可惜的,能不能把这个做完,后面如果有新的类似需求再用工作流”,小菜想着今天的任务要推到重来,有些不情愿地说道。
“作为一个刚入职的员工,想尽快地做出成果,完成工作任务固然重要,但作为一个程序员,必须要对自己要有严格的要求,要时刻想着有没有更好的设计,有没有更好的编码实现,有没有更好的算法提高系统性能,能不能通过自动化的工具来减少自己的重复工作,这些对程序员未来的发展很重要,所谓经验,就是由不断踩坑不断填坑的过程,坑填多了,总结多了,下次碰到坑就能绕过去,经验就涨了,如果只踩坑,不填坑,不总结就光涨工作年限,如果我现在告诉你前面有坑,你又什么要跳进去?,我见过很多程序员,有的工作了几年,和毕业相比没什么长进,有的短短一年就比有三年工作经验的进步快,这正是对自我严格要求,对新技术保持足够的热枕,并勇于实践。”老鸟语重心长地说道。
“好的,我晚上就看工作流”,停了老鸟一席话,小菜的战斗力又回来。
老鸟看看了时间,不自觉已经和小菜谈了一个多小时,收拾了下,和收获满满的小菜下班了。
“要是拿到需求多问一下,多研究思考下,说不定今天的工作就不用白做了” 小菜想到。
下篇文章谈谈如果自己实现一个工作流,应该如何设计并实现。
向《大话设计模式》致敬。欢迎访问我的网站
JavaCode:http://code.admineap.com
AdminEAP:http://www.admineap.com