从一名技术开发人员到实施人员的蜕变,从不同的角度看待同一个问题,或许会有不一样的结果。这里记录一下最近一个项目实施的案例,非常有感触!
一. 项目情况简介
本次项目是给一个国外生产型企业做仓库方面的系统,其中有一个功能就是给仓库做一个电子看板。所谓的电子看板就是在一个大屏幕上显示仓库进料和出料的情况,在大屏幕上显示指定数量的单号信息,就和医院的叫号系统一样,每行数据不停的向上滚动。
上面这个功能其实非常简单,就是查询相应的数据在屏幕上显示即可. 仓库每天可能收到20多个订单的进料单据,系统将单据分为三个状态: 待收货,收货中,收货完成
待收货,收货中的订单要在屏幕上轮番显示,但是屏幕最多只能显示6行订单,其余的隐藏,当第一行滚动消失,第二行替补上去,隐藏第一行显示。效果图如下:
整体数据往上滚动,当1 数据消失,3数据在最下面显示。
二. 不同的开发人员如何去实现这个功能
(1)A 开发人员想法:
使用WinForm 或者 WPF去实现一个这样的效果,特别是WPF实现的效果非常炫。最主要的是WinForm或者WPF对元素坐标的控制非常好,要使得内容移动只需要将其他的坐标处理移动就好了,然后加上一个线程或者定时器完全可以搞定。
(2)B 开发人员的想法:
最好使用Web页面来实现,然后使用投影或者外接显示器投到大屏幕。 Web实现的方式非常简单,网上还有现成的案例,只需要修改样式,颜色等就可以了,最关键的是web中可以使用jQuery,实现这样的效果一点都不难。
(3)C 开发人员:
机场那个啥都是使用的LED屏幕,使用这个高端大气上档次,只要我们提供相应的数据,然后找一个LED屏供应商将数据显示就可以了。
从以上三个人来看,对于同一个功能的实现都有着不同的看法,千万不要认为这三种方案有什么问题,其实三种方案都能够实现客户所要的效果。
说明问题:一个问题的解决肯定不是没有办法或者只有唯一一种办法。 以前我做程序的时候想问题也就局限在自己的思维逻辑中,除了这个就不会有什么更好的办法去解决。
三. 三个技术人员的方案
先说A开发人员: 在功能正式开发之前让A做了一个简单的Demo, 但是做了几天A还是停留在界面元素的控制上,而且文字的移动效果也不理想,跟别说后面的漂亮还要动态的去读取数据等其他的操作了。 其实A对WinForm和WPF技术不是太了解,他只是想通过这个来加强一下自己的技能。 A的方案有点在于:界面元素的坐标可以严格控制,这样在处理元素的移动的时候比较容易实现,缺点:因为界面的元素太多,而且内容在不断的变化,所以最终页不知道具体要处理哪个,理不清头绪了。
再说B开发人员: 使用Web界面然后投影到屏上,我曾经作为技术人员,我也比较认可这种实现方式。 要实现这样的一个效果其实也不是难事,jQuery中有动画处理的函数,实现起来应该比较容易,而且网络上有先天性的资源,可以解决一个大问题,看似非常完美的方案。事实上最终也是让B来开发实现的。
C开发人员: C的想法有点脱离技术层面的考虑,A和B都直接提到了用什么编程技术,而C不是这样的。所以说C的想法如果放到程序猿的眼中比较另类,但是C的确是最符合客户索要的最直接解决方案,因为客户不懂什么WinForm,WPF,jQuery。 但是C的方案没有得到认可,对于重新安装一个LED屏来说又是一笔开销,而且客户已经有现成的屏幕了[俗称电视机]。
在第一次跟客户谈这个问题的解决方案的时候,我是比较认可C的想法的,刚才也已经说了C最能直接让客户理解和接受,客户明白LED屏是怎么回事,不知道什么是WinForm,WPF,jQuery。 但是后来又否认了C的想法,问题要从客户实际出发,利用好自己现有的资源和客户的资源这个才是最重要的。首先公司的技术擅长的是Web方面的开发,而且客户已经有闲置的屏幕,如果做LED还需要其他外部供应商。A的方案直接就枪毙了,首先给人的感觉就是技术方案不可行。
问题说明:
(1) 善于利用现有的资源(技术,人员,硬件,软件,客户), 软件项目不只是将代码写完没有BUG就完事了,写代码只是一个项目中非常少的一部分。
(2) 项目的开发要以实施为基准,一切的开发要以实施客户使用为前提,当然如何开发是实施和技术之间是可以协调的,不存在一个压倒另外一个说法。
(3) 开发人员的思维过于局限,或者说没有真正去理解客户的想法。
(4) 愚蠢的给客户说你要告诉我明确的需求我才能给你开发。[这是我以前经常干的事情,从做了实施之后明白:客户根本就不清楚自己的需求是什么,你要做的事情是帮客户理清楚需求并且给他解决,否则你直接去做码农,码畜好了,你对客户来说有什么价值]
(5) 网络是工具,不是玩具,要善用网络工具。
四. 技术问题
开始制定好以B的方案来解决这个问题,而且在正式开发之前B已经做好了一个Demo,说明技术问题已经解决了,要做的事如何完善这个东西。
(1) 页面加载的数据行数不定,可能是3,4行,也可能超过10. 但是要求是如果超过6行数据,界面上显示6行,然后循环滚动
(2) 界面的数据要从后台动态去读取,并且定时更新
(3) 读取订单的数据不能直接到数据库读取
(4) 数据导出到Excel,然后人工去维护Excel中订单状态
因为功能的实现是使用jQuery方式来实现的,写了一个jQuery方法来处理这个效果,简单代码如下:
var items = []; //定义一个数组 var currentIndex = limit; //当前要移除的对象索引 var total = 0; //显示元素的所有个数 var height = $(this).find(‘> li:first‘).height(); //获得每个条目的高度\ //将所有的元素存入数组中 $(this).find(‘> li‘).each(function (i, item) { items.push(item); }); total = items.length;//计算如上数组的长度 $(this).parent().css({ height: height * limit }); $(this).find(‘> li‘).filter(‘:gt(‘ + (limit - 1) + ‘)‘).remove(); var listItem = $(this); function Sky() { $(listItem).find(‘> li‘).filter(‘:lt(‘ + (limit) + ‘)‘).css({ opacity: 1, height: height }); $(listItem).find(‘> li‘).filter(‘:gt(‘ + (limit - 1) + ‘)‘).remove(); var $insert = $(items[currentIndex]).css({ height: 0, opacity: 0 }); $(listItem).append($insert); $(listItem).find("li:first").animate({ opacity: 0 }, 1000).animate({ height: 0 }, 1000, function () { $(this).remove(); }); $insert.animate({ height: height }, 1000).animate({ opacity: 1 }, 1000); currentIndex++; if (currentIndex >= total) { currentIndex = 0; } setTimeout(Sky, interval) }
问题1: B 人员测试使用的多于6行的数据处理的,而且数据不变更,效果非常好。现在出现了少于6行的数据,结果出现界面显示的数据就少了1行[不是真正的少了,而是被影藏起来了]。 假设属于有10行, 1-6显示的时候 7-10影藏, 1 滚动消失,那么7显示,1添加到最10的后面,一次类推。所以在少于6行的时候 比如3行数据,只能显示2行了,而要求是3行都显示才行。
问题2:当数据滚动时间较长的时候,因为动画消失和上滚动的循环的时间频率不一致,导致页面出现滚动条,最后数据就乱了。
问题3:读取Excel文件数据问题,B的反馈是如果Excel文件关闭读取没有问题,而打开之后时间读取格式有问题
问题4:Excel内容变更如何通知界面数据改变
问题1-方案:
这个问题难度不大,只需要修改相应的判断就可以了。如果所有的数据小于6行的时候,第一行显示数据消失之后直接添加到末尾不处理影藏的效果。
问题2-方案:
这个问题将B难倒了,效果已经做好了,但是就是滚动频率不一致,导致后面显示的元素越来越多,界面上能够看到的订单多于6行了,而且出现页面滚动条。最后还是我给他出了一个主意: 每次滚动变化的时候盘点显示的内容是否已经超过了6行,如果是的那么设置其属性影藏或者删除该元素。
$(listItem).find(‘> li‘).filter(‘:gt(‘ + (limit - 1) + ‘)‘).remove();
这个问题折腾了B好多天,他一心想着要去调整滚动频率和间隔时间,因为在你没有完全计算准确的时候是很难让两者达到共振的效果的。跳出自己的思维模式可能问题很快就解决了。
问题3-方案:
这个也是困扰B非常长的一个问题,一直没有解决。直到我看不过去了,我去看了他写的代码。
tempEntity.Forwarder = table.Rows[i][8].ToString(); Forecast = table.Rows[i][9].ToString();
第一句是读取Excel中日期年月日部分的,客户Excel中 一列是年月日,还有一列是 时间。 第二行是读取时间的。现在的问题是,客户要频繁的去修改Excel中的内容,所以每次客户打开Excel之后就不会去关闭这个Excel。
B就懵了,如果不关闭Excel,因为Excel被打开占用所以读不出来数据。"被占用了读不出来", 我不想说什么。我看了效果之后,打开Excel之后其他的数据都可以读出来,就是时间日期这一列读取出来不是日期格式,数据还是读取出来了,是一个double类型的值。
我断定这个问题与Excel是否被占用没有关系,否则其他的数据可能也读不出来,唯一的可能性就是Excel中的表格数据有问题或者是类型的问题。
这个让我想到Excel中的一个现象,一个单元格中输入一个很长的数字,当你编辑的时候会一一长串数字显示,其他的时候会以科学计数法来显示,这个时间应该和这个类似,确定应该是数据类型引起的。
DateTime date = DateTime.FromOADate(ConvertHelper.ToType<double>(Forecast) + ConvertHelper.ToType<double>(tempEntity.HHMM)); tempEntity.Forecast = date.ToString("MM.dd.yyyy"); tempEntity.HHMM = date.ToString("HH:mm");
我帮其调试问题,将以上几个值取出来测试,发现这个值就是时间格式的另外一种计数方式,发现问题,问题解决。
问题4-方案
这个涉及到一个频繁IO读取Excel中的内容问题,页面数据都从缓存中去读取,Excel 更新替换缓存中的内容,避免去直接读取Excel。
五. 经验总结
(1) 技术人员除了发现问题之外还要去想办法解决,很多人很容易找问题,但是很难去解决问题。
(2) 使用推理分析的方法去确定问题在哪里,对症下药。
(3) 善于倾听其他人的意见,融合大家的想法可以更好的去解决一个问题。
(4) 开发人员不要活在自己想象的世界里面,去学习了解一下别人的想法可能对你有很大的帮助。
(5) 写软件最重要的实用,好用。技术的本质是解决问题而不是看哪个界面做的更加漂亮或者使用了多少新的技术。
(6) 技术的选用要符合实际,切莫随波逐流,最终项目失败抱憾不已。
(7) 多接触用户,听听用户的反馈,自己也实际去操作一下,你才能真正感受到用户的想法,你才能理出客户的需求。
六. 感触的一句话
没有玩过智能手机的程序员去做移动开发