注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

LabATSS

关注自动测试软件

 
 
 

日志

 
 

LabVIEW面向对象编程—初窥门径(5):开发方式漫谈  

2018-04-02 21:21:46|  分类: LabVIEW |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

引言:在去年年底左右(2017年11月底),由于单位业务调整,自己工作性质和内容发生较大的改变,由原先的计量参数日常运行检定改为软件维护与开发,遂开始着手对以往前同事开发完成的LabVIEW旧代码(直流电源校准/检定自动测试序列)进行重新梳理与维护,在此过程中开始边实践、边摸索的开发学习方式,应用面向对象技术(Object-Oriented Program)对旧代码进行了完全重新的改写,由于前段时间日常忙于开发工作,周末时间又要承担中年油腻男的上有老、下有小的生活“重任”,难得在春节及前后期间有一段相对空闲的时间,可以将近日的开发心得(设计思想、开发过程等)总结记录一下,以便日后回顾复习,并秉着互联共享的精神分享给大家,但是由于本人的工作内容为计量校准的测控行业,因此在实际代码开发实践时选用的案例为本行业的电学参数中的直流电源校准为样例,因此有其局限性,较为适合本行业或者是电子测试工程师们在碰到类似的代码开发情况下予以参考借鉴。

另外强烈建议大家在台式电脑上阅读该系列博客文章,缘由是:文章内容篇幅均较长,且图形化编程的截图显示效果要求大屏幕展示为宜,况且手机和平板等便携式设备易受干扰,导致碎片化式的阅读,从而恶化学习吸收效果;还请特别注意,该系列的博文并不讲述任何基础的LabVIEW面向对象概念与技术(基础部分内容将另行撰文编写),初窥门径系列重点是经典的设计原则在重构旧有面向过程代码的应用,实际发布面向对象工程代码中的填坑经验,因此并不适宜LabVIEW初学者学习, 如观看本文有云山雾里般的“恶心、头晕、眼花”等不适感,请立刻点击操作关闭页面,以免造成严重心理疾病,丧失了对LVOOP学习的浓厚兴趣!


目录:

LabVIEW面向对象编程—初窥门径(1):困惑





正文


开发软件最少需要三种不同立场的角色来共同协作完成:客户、开发人员和测试人员。一般来说,通常是由客户方(产品负责人或者是需求分析师)来决定需求,制定需求分析报告、开发验收测试和设定将要开发功能的优先级。软件开发人员专注于实现客户的需要并确保实现的代码能够满足验收测试的要求。测试人员关注于帮助客户创建验收测试并帮助开发人员通过哪些测试。这些角色和职责体现了关注点分离的特点。

 

在传统而经典的软件开发流程瀑布模型中,一般是从客户提出需求开始,接着分析需求并检查分析结果与初始需求的一致性,并且确保开发人员能够理解该需求的实际含义;开发人员创建设计规范来描述如何实现这个需求,编写实际的软件代码来实现那些设计规范,并将完成的后可运行测试的代码交付给测试人员;测试人员阅读需求文档,接着创建一些功能测试用例来验证这一程序是否满足需求,或者需要修改返工,最终当程序满足了预期的结果并通过了诸如性能与稳定性测试,那么就可以准备发布部署了。

 

在理想的情况下,上述开发流程会线性的逐一完成,但是实际情况是残酷的,由于沟通误解,说了什么和听到什么往往南辕北辙导致产生交流障碍,由此也就产生了错误,而由于错误的追溯和修改需要回溯多个线性步奏,增加了项目成本,更为可能的是由于理解有误增加了不需要的功能被添加到系统中,使得系统繁杂臃肿,难易维护;为了减少沟通障碍,降低浪费,更为敏捷的提供对客户要价值的软件产品,软件开发界又推出了敏捷开发流程,该流程强调以交付和迭代为核心的方法(包含确定优先级、最小化可行产品MVP,及时获取反馈),让软件产品在实际环境中去工作并迭代得到实际需求。

 

“这种架构(敏捷)之所以奏效,原因很简单,因为我看到的是人们实际上怎么工作的,而不是他们嘴上宣称自己是如何工作的!”— 敏捷领袖 杰夫·萨瑟兰

 

看完了外界实际情况,再回到我们身边实际的LabVIEW开发过程中,不管是瀑布式线性模式,还是敏捷迭代式的模式都很少采用,因为一般使用LabVIEW作为开发工具的工程师们都是个人独狼式的开发方式居多,该方式无需与他人进行沟通和协作来共同开发软件产品,往往是一人身兼数职:自己开发程序代码(开发人员角色),满足自己使用需求(客户角色),开发文档和需求文书则基本上没有,依仗着脑子好—全都记在心中,日常实际工程使用代替了测试,类似于运动员的以赛代练(测试人员角色),应用过程中发现问题有时间就自己改,没时间就纯手工补救一下,凑凑合合、修修补补的也能用,完全纯粹的手工作坊式的个体开发。看上去不可思议!?不够专业!!实则不然,其实这正是LabVIEW以前中早期鼓励的开发方式,直接拖拽,开发效率至上!也是目前国内大多数使用者的开发现状。

 

实际上回归本源,LabVIEW开发环境的初始诞生目标:“就是为科学家和工程师们提供一种便于他们理解的图形化编程方式来开发小型测控程序,降低使用文本程序语言的开发难度。”用大白话通俗的讲:“就是LabVIEW出品人——美国NI公司提供简易图标化的模块编程工具环境,让没有软件教育背景也不懂编程的工程师们通过图形流程拖拽设计即可完成任务编程,特别是无需掌握任何复杂的图形化编程基础(GUI)也能开发跨平台的桌面窗口应用程序,从而使得工程师们能够专注于自己的业务逻辑。”,所以在LabVIEW的前期版本中,NI公司着重推出各种的高层封装的工具包算法来提高专业开发效率。从另外一个角度来看,LabVIEW实际上是测控领域的专属开发语言(DSL:领域专属语言),相比通用的文本语言(C++ VB JavaC#)更加的聚焦某一专用领域,并且提供半成品(如大量第三方的仪器设备驱动库)和领域算法功能包,从而大大提高工程师们的开发效率。

LabVIEW面向对象编程—初窥门径(5):开发方式漫谈 - labats - LabATSS
 

随着中大型程序(>500Vi),远程分布等复杂测控程序的需求日益增长,在2006NI公司推出的LabVIEW 8.0版本时才刚刚提供了项目管理方式,可以让开发人员通过项目(.lvproj)来工程化的管理、组织、发布大型代码库程序,但是其可执行文件还是平面的文件存储库形式打包而生成的,同年8月份推出的8.2版本(20周年纪念版本)中推出了本系列文章的主题——面向对象编程范型(这让本来就不会编程的测控工程们情以何堪)。并且逐渐加强了对软件工程的支持,例如提供更多的软件工程代码发布选项(支持EXEInstall.NET AssembleLvlibpDLLSource DistuWeb ServiceZIP,更加便利的支持代码签入存档功能,增加了执行文件中的层级目录支持,增加lvlib库加强命名空间的概念等等。

 

虽然越来越新的版本提供了诸多现代编程语言需要的软件工程能力,但是由于开发年代久远并且要兼顾代码兼容性,LabVIEW大型项目的开发模式还是步履蹒跚,走的很患难!这也是全新的下一代LabVIEW NXG 推出时想要重点解决的问题之一。

 

回到我们的老本行计量自动测试开发本身上,多数开发者——年轻的计量(或者测控)工程师都是业余爱好式的开发,首先专职工作并不是软件开发,其次也没有经过任何入门或提高类的编程开发培训,充其量也就是在学校学过一门C语言编程,只是日常工作中有自动化测试的需求背景。想要解决自己的重复手工劳动的困难,而所在单位却又不肯投入真金白银去外购或者投入资源自行开发,因此只能自力更生地利用空闲时间,边干边学的使用LabVIEW开发个辅助自动测试的工具软件,提升一下自己的工作效率并相应的降低劳动强度。

 

由于是给自己使用,前述提到的三角色模型(客户、开发、测试)都是工程师们自己个人一肩挑了,也就根本没有的任何需要协作沟通的问题,由于没有程序开发、使用、测试、维护分离的主导理念,再加上开发资源(如时间、经验)受限提示帮助较少(或者就是自己使用无须提示和帮助),直接导致开发后果就是:程序开发出来自己能用,但是别人觉得不好用、或者不会用、甚至于不能用!当然也有一种可能就是有藏私的心理,就没有打算给其他人用的想法。

 

再过上个把年头,早先的开发者们一换工作岗位诸如晋升、换参数或者离职,个人心理一盘几:“艹,老子我辛辛苦苦、没日没夜地开发程序,不说发点奖金补贴吧!?结果到最后老子想报销个编程学习资料都扣扣索索、唧唧歪歪的,这不行那不让的!凭什么留给他们吃现成的!不能给他们留下!别说想看源代码学习就是用都别想用!”。于是乎,大家又都重新回到了Excel电子表格原始记录驱动,刀耕火种的纯手工打造匠心计量了。不知不觉几年过去了,又有一个新来的年轻人想:“这手动操作的工作完全可以编程来解决啊!”,一个新的循环轮回又开始重新上演了。

 

另外一个制约自动检定/校准程序开发的因袭是:往往开发需求是真实明确的,因为使用者就是开发者本人,但是往往开发者编程能力不能胜任完成开发软件任务,因此不得已降低需求要求,或者只能完成部分需求的实现并辅助一部分人工用以弥补的混合式使用方式,这也是程序不好用,不易用的核心原因。

 

即使某些单位人员、资金、设备资源较为充裕,如果选择申报课题项目式的软件开发过程方式,则在项目验收结束后缺少后期维护与持续迭代的研发,而协作外包式开发方式则缺少后期长期的技术支持,最后想着多花钱省省心直接购买国外成熟的软件产品,由于该类产品固定成型无法按国内特殊情况定制化流程与测量结果表示,且模型和文化与国内不符合,从而致使易用性较差,最终束之高阁,这里就不再展开写了,往事一提,都是一把酸辛泪啊!

 

根据我们自己以往多年的开发经历和流程总结了以下几点经验:

 

1.开发本行业专用领域软件肯定还是自主研发的更为可靠、好用,但是前提条件是也要不断地提高编程开发人员综合能力,充分学习和吸收外部技术创新点和功能列表。

 

2.代码是集体公共开发产物,知识产权全权归属于单位,非个人专属拥有,组内人员开源共享;单人开发、众人维护,任何人的退出都不得私自破坏和拷贝源代码。

 

3.从简单到复杂,从需求、开发到包括后期维护的软件开发是一个不断上升的迭代循环曲线,不断的重构旧有代码,消除越来越多的重复(冗余)代码是我们开发的核心理念。

 

4.开发代码的架构与开发人员组织形式要相匹配,强调分工合作,重点程序员开发基础核心功能模块和高层调用策略框架,应用程序员开发侧重参数领域直接开发,全部的开发人员都要有功能模块服务意识,追求最大可能的通用性。

 

经验的第一条决定了我们的开发方式为自主研发,核心代码独立可控,不搞合作和外购而产生过多的依赖性,重点培养核心编程人员的编程能力,以传帮带的形式不断扩大编程队伍,让更多的计量测试工程师掌握编程的技能。另外也不断的跟踪国内外的相关领域行业软件情况(国外校准行业软件见以前的一篇博客文章-上链接),吸收好的功能特点移植到自己的开发框架和测试程序序列当中去。

 

经验的第二条使我们积极倡导并贯彻实施的软件开发文化,明确了代码的产权和开发者间的相互关系,强调核心价值观“开源共享”,使得代码有人开发,便于维护,大家共同提高,相互借鉴并尽可能地代码复用,在再次开发时,可以充分利用前人的开发代码基础叠加开发,不搞重复开发;另外在实际工作中往往能力越强的程序员,就越具备开源分享的精神,特别是互联网时代开源代码精神使得编程技术信息的获取变得极其的便捷,不断的学习提高,分享代码成为每个编程人员的基本素质要求。当然在实施的过程也出现了私自分支拷贝,谋取私利的不良事件,但是不会影响我们继续实施组内开源共享的精神。

 

最为重要的经验是在开发流程上,由于没有专业的软件工程开发流程的经验和背景知识,都是野路子摸爬滚打的实战练习,所以我们自己非常类似于丐版作坊式开发流程,更倾向于多编代码多实战测试的游击战开发模式,有时候商业校准工作任务时间紧迫的情况下,往往都是边开发、边使用、边修改的即时战斗开发模式,也是由于前期设计少,致使快速开发产出的实际工程代码可用,但是重复冗余代码段多,编程风格不统一,后期维护困难的弊端,因此就需要不断反复迭代开发,消除重复冗余代码,底层的冗余代码通过子函数Vi封装成库函数提供上层调用,上层模板化的重复流程代码片段则提升到统一高层调用框架中,通过不断的重新梳理、重构旧有的代码的过程,持续打造可用的代码库和生产代码。

LabVIEW面向对象编程—初窥门径(5):开发方式漫谈 - labats - LabATSS

 

最后的经验是,在开发组织形式方面,随着开发量和开发范围的扩大,也需要组织形式和开发代码的高层架构形式相适应,我们原先的开发高层架构形式是上层框架调用底层测试序列的模式,因此原先的开发组织形式就是两、三人进行上层调用代码、共用模块以及基础软件库包的的开发与维护,更多的各个参数计量测试工程师负责各自领域专业计量参数的具体型号的底层测试子序列开发、维护与测试。这样的结构能够促使关注点分离,提供更具良好服务功能接口,降低软件系统之间的耦合性。

 

在本次应用面向对象设计原则进行旧由测试代码序列开发过程中,又体验并进而总结得到到了以下好的开发经验:

 

l  技术洁癖应避免LabVIEW现在能够提供两种主流的编程范型——面向过程和面向对象,一般的测控程序当前还是以面向过程为主流范型,面向对象较少采用或者较难应用,一般开发者往往不喜欢将两种模式混合穿插使用,原先我们也是想等自己的开发组面向对象技术能力更加成熟时,再完全开发一整套全新的测试测量框架,但是通过本次实践代码更新过程,将面向对象技术开发的底层测试序列与上层基于过程的动态调用框架结合在一起进行混合式编程范型的开发,通过增加必要的抽象适配层提供良好扩展性,并且在实战中能够更快的领悟面向对象设计原则SOLID,因此采用新的面向对象范型并不需要大范围的重新编写,可以采用逐步模组替换,逐步推广的策略,特别是要能够容忍同时并存两种范型,但是并不是鼓励穿插使用,还是以逻辑范围划分为功能模组,在一个单一模组库内采用一种编程范型,最终的目的还是向着全面的面向对象技术范型的完整解决方案前进。

l  模拟仿真促开发,面向对象技术由于应用抽象提供了逻辑概念层(MAL)和(HAL),可以继承于抽象提供一个模拟仿真类型,该类型特别有助于测试对象间的交互模型协作接口,有利于整体分解功能职责到相对应的类设计中去,并且通过模拟仿真,能够快速搭建仿真运行的演示(DEMO)程序来辅助上层模块逻辑的面向对象设计,能够用客户程序代码的角度来促进抽象的设计;另外,从某种意义上来讲,模拟仿真也提供了一种更为便捷有效的需求、功能测试方案,当在运行一个最简可行功能测试时,能及时看到实际效果,不是盲目的增加功能和优化性能,避免过早的关注具体型号实物操作细节,以及底层测试细节影响上层抽象设计决策。另外,模拟仿真还能显著降低开发成本,由于是计量测控软件是控制设备完成测试任务,也就离不开硬件资源的支持,而在开发软件过程中长时间占用计量测试核心生产资料—设备,进而影响日常工作产出,造成较大的资源耗费,况且实际上往往采用面向对象开发时, 60%(预估)的时间都是在设计类与职责分配、对象通信协作的概念领域开发,并不需要过早的涉足与硬件逻辑操作的具体细节,通过模拟仿真硬件充当实际设备的替身,完成基于硬件抽象层(HAL)的高层模块测试策略与指标封装后,在集中通过继承扩展至更为具体细节的操作类,从而大大降低开发该类程序对核心硬件资源的无效占用时间。

l  及时集成补设计,由于本次开发是替换原先的底层测试序列,因此为了继续保持对原先的代码兼容,需要多次及时的与原先的调用框架进行混合式发布即集成发布测试,通过整体集成发布后的半成品演示(DEMO)测试,时刻铭记为什么要做这件事(即上下文)能帮助我们改进当下正在做的事情,不断迭代修正开发前行的路线,以免偏离正确的需求方向。及时集成还有一个附加的积极心理附加暗示,我们也称之为“看得见的愿景”,有时候开发周期较长,长期抽象概念的云里雾里中兜兜转转,开发人员容易陷入开发倦怠期,而集成发布可执行文件完成后,可以演示或者部分实际功能可用的半成品功能效果的展示,能让开发人员建立起“自己正在开发有价值的软件工具,按照目前的效果继续努力就会更快能够实际应用了”的积极思维,从而将开发效率维持在一个较高的水准之上。

 

总结,开发流程及方式对于LabVIEW兼职开发者和小型开发团队而言,很难确定什么是最好的!但是对开发充满了热爱之情,积极的通过多动手实战磨练、提升自己的开发技能,不断地反复迭代开发产出能工作的实际工程代码是业界大牛们共同遵循的编码实践。软件程序产品本身更像是一个生命体,需要不断的持续开发及后期维护和支持,一旦停下来就会僵化死亡。一个人独狼式的开发在程序开发初期,由于不需要沟通协作,开发效率上较高,走的也许比较快;但是开发团队定好合适的流程与设计好层次功能代码分工,开发能够走的更加远,持续的时间更为久远,涉足的范围更加广泛。面向对象编程范型的技术采用,让我们可以便利的应用模拟仿真测试,及时集成测试,而这些测试提供了多种形式的及时反馈,避免设计不足或过度,以及偏离正确的需求方向。

 

参考文件

《敏捷技能修炼——敏捷软件开发与设计的最佳实践》,Alan Shalloway, Scott Bain,Ken Pugh,Amir Kolsky, 郑立,邹骏,黄灵,机械工业出版社,2012

  评论这张
 
阅读(36)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018