近几年有个新名词,叫做软件考古学(Software Archeology),意在研究现有软件系统里面的各种东西,以供今人所用。在其他的工程领域,可能从来没有人研究什么水电工程思想或者机械设计心理学,但软件工程师似乎很喜欢制造这些稀奇古怪的名词,而且制造者往往都是一些业界知名的大牛,于是追捧者也不在少数。前不久听过候捷先生的课程,了解到他对标准模版库的理解之深,想必他也在不知不觉之间成为了软件考古学者,才可以把一些经典代码研究得如此透彻。对我而言,去静态的观察一个现有系统的结构,远远没有实际参与一个系统的构建,从而体验其一步步演化的历程来的激动人心。历史本来就是一门基于时间的学问。
正如我们把国内一些公司的PACS/RIS产品线从时间轴上展开,会发现一些有趣的相似之处,一些你原来觉得只有自己才会遇到的问题,在另一些公司可能同样会遇到。不少公司刚开始做miniPACS的时候,RIS和PACS几乎都是糅合在一起,一个明显的标志就是在工作站上看图和报告是在同一个进程内强耦合地运行。有些系统虽然声称有独立RIS服务器和PACS服务器,并且用Broker来集成他们。但国内的应用环境太小,为了实现完整的诊断流程,只能把RIS服务器和PACS服务器和Broker全部安装在一台机器上,这真是让人尴尬。其实Broker应该是国外一些PACS/RIS前驱们提出的一个概念,不知是盲从还是想作为提高价格的筹码,很多做miniPACS的公司,以及很多想做fullPACS但市场环境又要求他们只能做miniPACS的公司,都不约而同地把Broker纳入他们的产品线,于是陷入了吃力不讨好的境地。
其实Broker只是这种高不成低不就的产品线架构的一个缩影,似乎能反映出当时大家对市场细分还没有太多的概念。其实国内很多中小医院,以及对信息系统还不太了解想先试探一下的大医院,都更能接受miniPACS的方案,比如只需要一些独立运行的工作站,能从设备上获得图象,然后看图,写报告,打印胶片,刻录光盘,甚至修改信息,然后把图象发送出去就行。于是灵活便捷的单机版工作站成为了热卖。与此同时,还有余力的公司,以及其实没有什么余力但还存有梦想的公司,终于把RIS和PACS彻底地分开。RIS提出了Brokerless的概念,自己提供DICOM和HL7的接口;PACS也可以面向整个医疗机构存储和处理更多不同类型的图象信息。这就有点SOA的味道了,每个系统业务完整,系统之间松散而清晰,于是Broker也不再只是做DICOM和HL7之间的转换,更应该扮演ESB的角色了。
于是,我们在PACS/RIS的演化树上看到了一个明显的分支,一个是更简单的miniPACS,一个是更复杂的fullPACS。如果把集成的工作放在这样的时间轴上,不难发现我们现在已经站在向更复杂和更松散延伸的分支上;因为另外一个分支更象传统医用设备上的嵌入式软件,需要的是独立和内聚。也许在这样的软件内部也会有很多松散的模块,然后在一个基础框架上组装起来,但这已经远离信息系统集成的概念了。
---
我总是习惯性地把集成分成几种类型,数据集成,工作流集成和桌面集成。这应该不是我的原创,倒象是很久以前在某个PPT或者网页上看到的。一般意义上的互联,比如DICOM, HL7或者非标准的数据共享,应该算是数据集成。我也愿意把简单的互操作也理解成数据集成,它无非是把带有命令语义的数据传给对方而已,而真正的工作流集成应该是一种有序和受控的数据流,符合IHE,符合那个什么工作流组织的标准,而且最好是基于一个工作流引擎来实现,于是可配置。关注前两种集成的人应该占大多数,也创造了各种千奇百怪的集成工具,从最简单的验证DICOM的命令行工具到巨无霸似的Biztalk Server。这些工具的一个共同特点就是在后台运行,这似乎让做集成的工程师有一种莫名的优越感,因为实现用户界面总被认为是实习生应该做的工作。然而对大多数用户来说,用户界面几乎就是软件本身——不记得这又是哪个大佬说的话,也没来得及细看CCOW对桌面集成的理解里面,有没有真正关于用户界面的东西,总之我所理解的界面集成里面,不仅包含CCOW提到的在同一台机器上不同应用程序间的相互通信,还包括这些应用程序应该具备统一的人机交互方式。也许这已经有点在讨论可用性(usability)的味道了,但在医疗领域,可用性却是避免操作失误和医疗事故的重要设计。
---
前面讲到PACS和RIS的独立实现,为了实现真正的弱耦合,除了服务器端的拆分以外,还有客户端的拆分。也就是把报告模块和看图模块分开成两个进程,然后在同一台机器(其实也可能在两台机器上)上互相通信,打开报告的时候可以看到图象,打开图象的时候可以看到报告。当时我们虽然知道有个CCOW,也没时间去研究,当时的市场似乎也不要求我们去这样做。后来有空回头看看的时候,才发现CCOW也是类似的设计。我们最初定义了一个消息分发服务,应用程序启动时候先到这个服务上注册一下,运行的时候就可以收发消息,服务根据不同的程序ID还可以进行消息分发。当然我们还要考虑消息的时序,同步或者异步,以及给Web应用和Windows应用提供不同的接口。最后发现当时的应用环境其实没有这么复杂,于是省去了注册,这样服务端也不需要维护客户端的状态,它只是做简单的消息广播;服务端的宿主也懒得用NTService,就放在一个WinForm的主进程里好了。幸亏没有事先看过CCOW,否则可能我们的项目里面除了那个注册接口的定义以外,还有更多的垃圾代码。我更喜欢一个可以慢慢长大的芝麻,而不是一个胖得快要爆炸的西瓜。
关于统一的用户界面,业界也有不少Best Practise。Syngo产品线算是其中的一个代表作,工作站上的主要模块可以用一个右边的选项卡来切换,然后每个模块里面图象显示区域和工具面板也有固定的位置和比例。如果你仔细研究,甚至调节图象的鼠标操作也有非常细致入微的设计,不管是普放的挂片还是断层的定位,不管是Zooming的比例还是Windowing的步长。这一部分的桌面集成,比如基于选项卡的界面结构,记录用户浏览和操作习惯的User Profile通常都是通过产品线共享的一些组件或框架来实现,的确难以定义成行业标准。不过象User Profile之类的配置如果能在厂家间共享,的确是件有趣的事,这样某个左撇子医生不管在临床的WEB工作站还是在专业的CAD工作站上都可以用他习惯的鼠标左键来调节窗宽窗位。想想其实类似的事情还挺多,比如Hanging Protocol和Key Image。而且在数据,工作流和桌面几种集成之间有时真的没有明显的界限。
就像GoF总结每个设计模式的时候总会讨论一下它的缺点,选项卡式的集成也有它的不足之处。首先,如果象“标签式用户界面的故事”文中提到的实现方式,就要求所有应用程序加载上来以后都会在一个进程里面运行,虽然.NET里面Application Domain的概念为每个应用提供了很好的隔离,但总会有些不方便的地方吧,比如你打开Task Manager,看到一个进程就占用了系统80%的内存,会不会突然下一跳。幸运的是,至今为止我暂时没有发现整个缺点会带来多大的影响,而且我也一直在寻找.NET里面有没有从一个进程里面动态地卸载一个程序集的方法。
其实选项卡式集成的一个更明显的缺点是不能同时看到两个应用程序的界面,比如这两个界面刚好一个是报告一个是图象呢?好,那我们就把它们分别摆在两个显示器上。这似乎能更好的解决这个问题,也是现在业界流行的做法。不过让我记忆忧新的是,当年做系统升级,让医生从使用单显示器切换到使用两个显示器的报告系统,医生和工程师都深陷炼狱,其间的痛苦难以名状。也许这应该牵涉到另外的话题,比如升级前的准备和客户服务相关领域的东西了,因为我也看到其他以前没有使用过单显示器报告系统的人欣然接受了多屏系统。其中的一个关键细节在于,医生常常需要拿现在的图象跟过去的图象相比较,在多屏系统上打开以前的图象的时候,希望打开当时写过的报告,同时也不需要关闭现在正在写的这份报告。我们显然不愿意当用户在一个显示器上选中某张图象的时候,在另外一个显示器上同步显示它对应的报告,这似乎看起来理所当然,但会导致报告和图象之间循环调用,从usability的角度,过多的自动化也会产生不便和混乱。
这应该用到另外一个Best Practise了,也许不见得是什么Best Practise,只是当时在升级现场重重压力之下的应急之策。因为大多数RIS都提供了在WEB上看报告的功能,通常是给临床科室使用的。为了在看历史图象的时候能看到报告,我们让医生点击按钮打开RIS一个的网页,网页上就是当时写的报告,这其实就把桌面程序和WEB程序给集成起来。我们知道WEB程序跟桌面程序最大的区别在于他们使用不同的状态控制模型,为了让医生切换到另外一份图象的时候,能够自动关闭不再使用的报告,我们把网页用IE控件嵌入到桌面程序里。于是才知道IE原来不只是一个简单的浏览器,而是一个如此灵活而且可爱的框架。就象COM一样,你感觉不到它,但每时每刻都在用它。
后来我顺道研究了一下HTML文档对象模型(DOM),从而有了象做网页一样用脚本来实现所有的用户界面的想法。大概是因为微软在IE上已是如此的成功,再也没有花大力气来维护这个曾经立过大功的可怜的产品,这个DOM里面很多不可预知的BUG,让我们这些期待着WEB和Window两种编程模型的统一的人望而却步。与此同时,微软推出了ASP.Net,似乎也是引导大家走向统一的一种approach,但在我看来,用不断往返于服务器和浏览器之间的一堆乱码来模拟Window编程中的内存的做法,不免显得有些愚蠢。于是也让原来名不见经传的XML DOM抢尽了风头,还摇身一变有了一个新名字叫Ajax。现在微软终于开始推XAML了,重新回归到HTML DOM时代人们一直期待着的编程模型,再加上ASP.Net带来的Code Behind技术,黑暗的世界里又重新看到了一些曙光。软件界实在没有什么新东西,经常只是一个一个地推翻重来,换个新名词,其实做的还是同一件事情。我在2005微软技术大会上看到过Vista的演示,记得里面也有一个电子病历的程序,在一个有点象电子游戏的界面上,3D头颅在不停地旋转,红色的心电图在兴奋的跳跃,整个界面设计真是让人耳目一新。不过到那天,其实我们也还得做同一件事情,那就是桌面集成。