就快要离开公司了,总想要说点什么。虽然在这里呆的时间不长,平时除了几个熟悉的同事交流的比较多之外,我对其他很多人知之甚少。无知带来的最大的一个问题便是傲慢和偏见,这是每一个人都无法改变的,即使你后天经过再多努力的修养与历练,也很难完全抹去这个问题,当然这里和个人或者说程序员这个行业的很多工作人员都不是那么喜欢说话有关;也就是性格和气质上面的东西有很大关系。
说回工作上,在公司的这段时间里我学到了不少东西,这其中有很多是和在学校里面所学的东西很不一样的,但却是现在企业要求要做的到的;另外,当工作了一段时间后你又会慢慢发现其实这些看似和之前学的很不一样的东西其实和最初学的最基础的东西是一脉相承的,所谓殊途同归,也就是这个意思。具体来讲,笔者参与开发的本公司的两个web系统,第四代政府物流服务署管理系统(以下简称tmis4)和职员更份管理系统(以下简称SDMS),接下来我将具体展开一些个人体会到的细节。
首先是tmis4,如果可以的话,我真的希望能看到关于tmis4的更多的资料,不仅仅是关于它的软件设计书(当然这个很重要),更多的是香港政府物流服务署这个政府机构,我觉得这是一个足以让我们尊重的机构。开发一个内部管理系统不是什么难事,至少对于一个成熟的软件公司来说是如此。但是想要开发好一个软件,如果不从项目的背景和具体需求出发,只是盲目的照搬生硬的一些概念和逻辑,那么很多事既无法做到令别人满意,也无法做到令自己满意。因此我认为如果对于一个从来都不了解tmis4的人想要快速上手并加入到这支开发队伍当中去,这篇文章会有很大帮助(当然这也是我在很久之后才找到的):香港两千司机解决逾17万官员出行,在此之前我对香港的印象是这里的居民以粤语、英语为第一语言,普通话为第二语言的一个地方,但是从我们开发的tmis4系统来看,香港政府的所有公车司机竟然全部熟练地掌握英语,后面通过上面这篇文章验证了这个观点,仔细一想这对香港来说并没有什么奇怪的,但是其政府物流服务署这个高效运转的组织却不得不令人肃然起敬,相比与大陆的公车司机,物流服务署从具体的组织机构、制度和人员的选拔具体工作来看,都要比我们高效透明的多,这也是最值得我们学习的地方,这里面的东西要比tmis4这个系统本身深远的多。说回tmis4,前面说到了关于tmis4的软件设计书,
后来笔者从开发文档中翻到了这个文件:TMISv4.0-SAnD-SS-SD.docx,虽然是一个纯英文的文档,但是通过参考这个文档,我们会对tmis4的整个系统框架模型有一个更深入的认识,尤其是其中涉及到的很多数据字典,更是十分重要,当然其中的诸如业务流程图、数据流图、UML图,都很考验一个软件设计师的基本功。有些人可能会觉得这些东西不重要,写代码才是最直接最重要的,其实这种看法本末倒置了,在软件开发中,编码只占很小的一部分时间,而做前期的一些准备诸如需求分析概要设计详细设计这些才是最重要的,技术的发展日新月异,千变万化,但是有些东西是不变的,比如上面说的那些图,这是万变不离其宗的基本思路,通过各种图来指导我们去开发,才会更高效,更有力。
接下来是具体的编码。编码是我们程序员平时开发做的最多的东西,但是如前所述,其实编码在软件开发当中应该只能占较小的一部分,但是这较小的一部分实际上却也是如此的重要。具体展开来说:首先是技术栈方面,要给tmis4下一个技术栈基调,则应该是:MS sql server + grails + spring + hibernate + groovy + java + vue.js 2.x + ES6 + js + vuex + vue-router + bootstrap + CSS + HTML + jBoss,主要用到了这些技术。具体来划分,则是前端、后台和数据库三大部分(当然还有一个服务器部分)。接下来将分别阐述笔者对tmis4中这些部分的理解。首先就是数据库部分了,这是最重要的,其实也应该是要求最高的,但是对于笔者目前的水平来说,对数据库还是知之甚少,只能粗浅的谈谈一些细节。首先从数据库选型来说,目前市面上的关系型数据库,MySQL、Oracle、MS sql server等几大主流数据库各有长短,分别适应于不同的业务领域。比如十分火爆的Mysql,由于其开源特性,在许多高并发,高流量的业务公司中是首选,比如阿里、京东这些电商平台。而Oracle在金融领域有着广泛的使用,sql server则在许多国企,政府部门使用较多。笔者在学校数据库课程老师就是带我们使用sql server学习的。说回tmis4中的数据库,其主要特点有二:一是业务内容繁杂,因此设计到大量数据库表,表中也含有大量字段,与之而来的就是各种约束、依赖、触发器……基本思路倒是不难,但是业务却很复杂;二是其含有不少存储过程,存储过程在特定的业务场合下还是具有相当作用的,其语法类似于VB,总的来说不难上手。但是面对复杂的业务逻辑却也是需要耗费相当精力才能做好,尤其是其本身不具备高级语言中的很多数据结构,怎样去表达数据的存储是一个不小的问题。
题外话,存储过程本身倒是备受争议,比如MySQL在5.0版本之前根本没有存储过程,在阿里巴巴的那本著名的《Java开发手册》中更是明令禁止使用存储过程,关于这个的讨论可以看这里关于存储过程的讨论。总的来说,系统管理工具无非是对数据库进行可视化展现的一种工具,当然展现的过程要尽可能的对用户友好。因而数据库的设计与开发毫无疑问是整个编码中最重要的一部分。
说完数据库再说tmis4的后台,tmis4的后台主要用到了grails框架来作为桥梁和数据库进行连接并且对数据表和视图进行model化处理再和前端进行交接。整个系统的构建思路依旧是经典的MVC设计模式,model层具体在tmis4中就是domain,其抽象了数据库中的部分表和视图,而controller就是具体的那些controller和service,view层则是前端显示部分。后台需要注意的细节主要有以下几点:首先grails框架在JavaEE框架族中比之SSH,SSM,Spring Boot这些名声相差甚远,所以相对来说其能够搜索到的参考资料也较少,更多的时候只能参考官 的官方文档,其使用的Spring和Hibernate框架倒是不必过于关心,因为封装的已很好,主要是groovy语言的一些特性需要了解,groovy本质上仍然是运行在JVM上面的Java系语言,它的语法其实很像JS,但是也参照了Java中的许多内容,关于groovy和Java的比较,这里也有一个讨论groovy。总的来说,用Java + js的思路去写groovy就基本没错了!groovy是一门偏脚本的语言,其实在我看来,如果非要选择groovy作为后台开发语言,那只能有一个解释:即开发者既不想放弃Java平台又希望用js的语法风格去写Java,否则的话为什么不选择node.js或者Java呢。也因此,groovy里面其实也有些“坑”需要踩,毕竟这也是一门新的编程语言,比如它的闭包特性,我们经常会遇到需要循环遍历集合的情况,groovy中定义一个集合的写法更像是Java中定义了一个数组,由于有闭包的特性因此groovy中支持使用each来直接遍历集合中的元素,但是each遍历毕竟不是循环,因此break跳出循环的写法在each中是无效的,如果要实现这样的逻辑还是得使用for或者while循环,类似的“坑”在groovy中还很多,需要慢慢去踩。笔者曾经看到的大部分资料中在提到了使用groovy语言的一个好处就是比Java更加简洁,可以用更少的代码表达更多的东西,的确如此,但是如同js一样的动态类型的语言,弱数据类型,这会使得程序的可读性下降不少。
对于后台部分,还有最后一点,就是关于调试的部分,如果使用sublime来作为编码工具的话那很容易会遇到一个问题就是你没有调试器,那么就必须选择第三方的调试工具。诚然在控制台上直接输出原生的jvm调试信息也没什么,但是可读性太差了,tmis4和sdms在后台调试方面都使用了cmd命令行的加强版本ConEmu64,相比之下调试出来的结果要好上不少,但其实也就那样,比之eclipse和IDEA中的调试要逊色不少。
类似这样的新特性新写法还有很多,笔者刚来的时候对这些几乎是一无所知,如前所述,面对新的知识的学习爬坑之旅是痛苦的,但却也是必须经历的。以上所讲的以tmis4中涉及到的ES6的写法,实际上ES6新提出的内容很多,需要注意的地方更是数不胜数,以后还会遇到更多。另外就是js的部分(主要指ES6之前的js),js本质上只是ECMAScript标准下的一种实现而已,除了js,其实还有微软提出的typeScript这些也是ES的实现,和前面说的groovy一样,js作为一门脚本语言,具有动态类型弱类型的特点,因此如果是之前写习惯了Java,c++这一类静态强类型的语言的话刚刚写js会觉得有些不适应,就和groovy中的def一样,js中的一切变量都是var(当然现在有了let),集合是var,对象是var,数组也是var…如果要说在tmis4中一些关于js的细节的话,那笔者想说说dom文档和MVVM框架。在vue的官 上说vue是一种渐进式的js框架,这句话挺难理解的,在一些vue的教程书里面都提到过vue是以数据为驱动进行数据与视图的双向绑定的框架,所谓的MVVM框架,在很大程度上也是指双向绑定——即当 View (视图层)变化时,会自动更新到
ViewModel (视图模型),反之亦然。 View ViewModel 之间通过双向绑定(tdata-binding )建立联系。
这有别于传统的jquery等前端框架采用dom节点来控制前端程序的响应变化,vue的这种做法更加简洁,在SPA(单页面富应用)型的前端中,使用vue进行组件化编程,可以在很大程度上减少重复的开发工作,尤其是在设计好前端显示所需要的公共组件之后,后续的开发只需要在父组件中调用子组件并修改传入的参数即可,使得前端开发变得更加简单,当然设计公共组件的难度不小,这是vue开发中的一个难点。
如果在接手开发时公共组件已经准备好,那么在开发过程中则需要仔细的了解需要用到的公共组件的原理和特性。下面以一个例子来具体说明公共组件的细节。
如图
名为Pagination的公共组件是tmis4中自定义的用于显示分页效果的组件,个人觉得这个分页组件写的还是不错的,之所以这么说是因为这个分页组件是笔者看到过的为数不多的功能十分齐全的分页,作为对比,我们可以看看一般主流 站的分页
这些分页虽然说平时使用已足够(很少有人会翻百度翻到第二页),但是有些时候提供能够跳转到指定页面的功能更好,比如淘宝就是这样的:
这种分页明显功能更加齐全,也是比较完美的一种分页了。具体来看Pagination组件,首先可以先看其html部分,
在div层中以li列表显示页面,这里面就用到了vue特有的指令v-if和v-for,这两个指令类似于JSP中的JSTL表达式,本质上就是条件渲染和循环显示dom的。这上面具体显示的数据带有{{ }}标记的都是挂载在vue实例上的数据,这些数据就可以认为是MVVM中的viewModel,已经被vue进行了双向绑定因而可以实现响应式的更新,即当在js中改变vue实例上的数据后相应视图也会即时更新。那么vue实例是一个怎样的存在单文件组件中看不清的话,我们可以在vue的字符串中看,如图:
在一个html文件中我们创建了一个名为app的vue实例,打印这个页面的window,结果如下
,名为app的对象在window对象之中,这就是vue的实例,在这个实例当中包含了所有可以调用的vue的特性,比如computed,data, watch, updated, el, refs等等,可以看到data中的数据的输出结果不是预想中的结果,而变成可Getter和Setter函数,这正是vue.js响应式系统的奥秘,也是其最大的特点之一。换言之,所有vue实例上的数据都被vue加上了Getter和Setter方法因此当我们更新数据时就会触发这两个方法因此系统得以响应更新视图,当然这个过程其实非常复杂,具体可以参考这里vue的双向绑定原理。总之我们应该要有一个vue的双向绑定的原理雏形,通过这个认识再去处理vue中一些原本看来奇怪的问题也就很简单了,比如,Vue.set()的使用:受现代 JavaScript 的限制 (以及废弃 Object.observe),Vue 不能检测到对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。如果要添加data对象上不存在的属性使得页面可以渲染这个属性的话,就必须用Vue.set()方法。
关于vue的内容有很多,这里只是例举了几个笔者印象深刻的部分,向其他关于vue的知识比如vue的生态系统中的vuex,vue-router笔者最近也在慢慢学习。另外还想说说sdms,sdms本质上和tmis4所用的技术栈一样,只有少数差异,比如说框架的版本不同,但是相对来说sdms的功能要更复杂。笔者最近一个月都在写sdms中的自动化测试功能,在没有任何参考资料的情况下初步完成了这个功能,可以说是满纸荒唐言,一把辛酸泪!只要autoTest, dutyRoster, dutyRecord这三个页面的按钮不发生变化,这个自动化就可以进行;只要不出现数据库保存时间过长的问题,这个自动化测试就可以正常进行,而且具备一定的纠错能力。本来作为一个脚本,按钮和页面其他dom节点的变化是无法影响到脚本的自动化进行的,但是由于vue本身的问题让这两者联系起来了,如前所述,vue.js是一个以数据为驱动的js框架,而作为自动化脚本而言就需要精准的操作dom节点,vue正是把我们从dom节点时代带入到了MVVM时代,此时要用vue来操作dom节点其实是多此一举了。由于是SPA型应用存在大量组件复用,因为使用id标记dom的办法并不好用,vue本身的ref属性又难以调用,因而只能使用document的element样式数组了,然而docment的样式数组会随着本样式dom节点的变化而变化,并且没有规律,所以说如果参与自动化测试的页面的相关样式节点如果有增删,那么会导致很多地方的样式节点获取紊乱,解决办法就只能是重新对照这些样式节点数组的下标。在前面两个条件正常的情况下,自动化测试可以正常使用,目前还差SDO RO EO账户的自由选择这个功能,只要这个功能完善了那就完全完成了autoTest。
毕竟是技术行业,我的工作总结大篇幅都是开发方面的,说到这里这个总结也快到了尾声了。实话讲,技术发展日新月异,更新有多快,变化有多大,其实并不重要,尤其是对于一个企业来说,我始终认为人情和人心才是最重要的,没有这个,其他的都是枉然。庄子宁愿在烂泥潭里打滚也不愿意接受楚威王许以的宰相之位,因为他知道在哪里才会活得快乐。对于程序员这个行业来说,就如同我最开始说的,可能很多人不是很喜欢动嘴说话,但是交流的方式有很多种,言语只是其中的一个方面,真心实意的人,你无论如何都会感受到他的温度,在我工作的这段时间了,我就遇到了很多这样的同事,很感谢他们,再见!
文章知识点与官方知识档案匹配,可进一步学习相关知识Java技能树首页概览91536 人正在系统学习中
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!