医疗卫生行业中的领域模型

不久前写过一篇关于医疗信息化领域的软件工程的文章,现在回去看,发现确实有点题目太大、内容太少的味道,用现在一个流行词汇,叫做标题党。其实写博客我一向不太重视标题,也常常文不对题,因为主要还是写给未来的自己看的,同时也顺带跟志同道合者交流交流,没必要在内容和形式上推敲这么多。原本这一篇的出发点想以领域模型为主的,但是内容可能比较杂,当作上篇软件工程的续集也是可以的。

几个月前参加了CSDN组织的一个活动,活动的主题是架构设计。课上主办方利用新浪微博让听众和演讲者进行互动,很有意思,但对于包括我在内的大多数与会者来说,大部分的时间还是竖起耳朵在听。其间引发了一个关于领域知识在架构设计中究竟占多大比重的讨论,看得出几位演讲嘉宾(包括听众在内)在这个问题上的看法并不完全一致,却都采用了非常官方的姿态把分歧屏蔽掉了。其中一位嘉宾提到,领域知识确实很重要,但是如何把它整理和表达出来,往往是十分困难的事情。

确实,任何东西在没有表达出来之前,在工程上都是没有实用价值的。你可以写出很好的需求,做出很好的设计,因为你深入理解了你的产品所服务的领域,并利用了这些领域知识来质问、衡量,并最终改进你的方案。但这些领域知识在哪里?没有文档,你就是拍脑袋。只要是拍脑袋,就经不起工程的推敲。好吧,领导发话了,现在进度这么紧,推敲这么多干嘛?确实也是,工程核心就是权衡,权衡下来还是进度要紧,那就开始做吧。没过多久,系统越做越大,这么多需求你实在分析不过来了,很多重要模块也要交给其他人设计,但他们可能刚入行没几年,也可能在互联网或者金融领域做了很久,但对医疗还陌生,你放心吗?你做好了频繁召开评审会议的准备了吗?当你多次评审之后才发现,你在会议上花掉的时间,某些规格说明书和某些设计方案早就可以做出来了,何必需要他们呢?等你慢慢把他们培养起来,哪天人手不够了,需要补充新人,你又要重复这个过程吗?经历过这些磨难之后,你最初承诺的进度得到兑现了吗?

其实在软件工程界不断翻新的时尚潮流中,对领域知识的关注始终处在一个边缘化的位置。其中缘由也是不难理解的。至今为止,软件工程界的主流方法和工具,主要还是几个大厂商推动的,特别是IBM和微软。从无所不包的RUP,到近年火热的敏捷,说白了还是换汤不换药;从COM时代的面向组件到,.Net时代的面向服务,有时候似乎只是用不同的方法把同样的问题重新解决了一遍。他们在这些方面不断地推陈出新,吸引大家的眼球,也许是因为他们只擅长这个,而且他们确实不了解领域。关于这一点,近年来这些公司在医疗行业的艰难处境可以作证;如果你说这可能只是他们商业上运作得不好的话,看看技术上的DSL吧,确实是很有前景也很有难度的一个方向,微软搞了好几年,现在也没怎么提了。

经历过几年前对RUP的热衷,到如今对敏捷的追捧,又让我想起《敏捷迭代开发:管理者指南》书中观点:其实所有软件过程几乎都可以从RUP里面派生出来,不管是多么瀑布还是多么敏捷。记得以前有人曾经被问到:你们项目用的是什么过程方法。我当时告诉他说,不管是什么,你都说是RUP,肯定没错的。其实我要说的是,在真实世界中,就算行业或者组织提供某些统一的指南,但每个项目采用的具体方法都必须是独一无二的。软件项目的差异来源于人的差异,这也意味着项目的控制者应该根据这些差异来选择甚至探索(比如个人喜欢通过一些自适应的方式)最适合的方法。当然,自适应的方式往往需要好的团队决策模式相配合。温博格曾对好几种团队决策模式及其适用的团队特点进行过分析,今天的主题不是管理,所以就不再展开了。

不过关于决策机制,特别有意思的一点是,决策的最佳产生机制未必跟组织结构是一致的。领导要做最终拍板,这是没错的。但如果一群人意见不一的时候,到底该听谁的,才能取得最好的结果,并且保持风险可控?大多数老板都会选择沉默,并仔细分析,最后再表达意见。有些老板也会跟大家一样积极表达意见,并做好了在意见受挫时表扬下属的心理准备;或是没有这个准备,最后只能为了维护自己的权威武断拍板。到底采取哪种方式,才能在团队中产生出最优的决策呢?有时最优方式的选择,跟我们最初的直觉判断未必一致。

最近程序员杂志连续几期报道了几位软件工程大牛发起的网上签名活动,旨在用一些简洁和基础性的核心实践,结束业界浮躁的概念炒作,并试图提升软件工程理论的学术高度。这确实是一件有意义的事情,大概也是在认知领域没有取得突破之前,软件工程领域唯一值得去做的少数几件事情之一了。但我还是有点为他们担心,如果它走回RUP那种无所不包的老路上去的话,最后的结果也许什么都不是;不过相信他们应该能够做好,毕竟他们可以吸取很多前人的经验和教训,特别是在目标的选择,以及技术概念的营销策略方面。

另外,现在想起来,在这少数几件值得做的事情当中,也许为各个信息化领域建立软件模型,应该也能算是其中之一。

让我们抛开业界的功利性时尚,翻翻真正的大师级作品《软件工程 卷3:领域、需求与软件设计》吧(虽然里面的很多形式逻辑会让包括我在内大多数读者望而却步)。很有意思的是,这本书在章节编排上把领域、需求和设计三者放在一个并列和递进的位置上。这里面包含的思维方式,让人深受启发。也许学术的东西就应该是这样,你可以通过它们看到业界一些华丽的概念背后的原理和出发点。

当然,我们并不排除,在没有专门针对领域或者业务知识进行整理和分析情况下,也可以成功开发软件的可能性。而且,这样的案例还比比皆是。毕竟业务分析的工作往往很大很有钱的组织才会负担得起,领域分析的工作往往更是有一些有政府背景的公共部门来负担,这些费用是不可能放到软件开发的项目预算中去的。

(这里说明一下,虽然很多人提倡把领域分析作为业务分析中数据模型的一部份工作来看待,而不把流程描述放在领域模型之中。但这里我还是暂且把它们看成两个独立层次的概念:比如在做医院的信息化规划之前,我们做的是业务分析,因为其中包含了医院对自身业务发展战略的考量,业务分析的结果一般会成为后续项目需求分析的输入,以及评审需求变更的一个重要指标,更深入的业务分析可能会涉及到BPR等,这一般都是咨询公司干的事了;而由国家卫生信息化部门出面,为整个行业提供的HIS或EHR基本数据集、集成标准如HL7RIM、作业流程规范如临床路径等,则属于领域分析的输出。也许有人把这些东西理解为标准化的工作范畴,但它们还是关注于领域属性和规律的发现,而不会涉及具体的技术规范,比如通信协议等。按照模型驱动的方法论,这些通信协议中的具体文法,恰恰则是由领域模型推导出来的。)

所以,大多数人的办法,还是尽可能把一些必要的领域或业务分析的工作偷偷地放在需求分析阶段里面做。去年我从广东同行那里听到了一个很有意思的做法:他们精心设计了需求变更请求单,通过这种模板工具来约束或促使需求的提出者(通常是有经验的医生或主任)以一种业务分析师的方式来思考,比如要求对一些需要显示的具体信息,及其业务来源和处理方式进行说明;并通过技术人员的审批来确保这些处理方式在技术上是可行的,审批结果可以直接反馈到医生,从而逐步让他们适应机器的思维方式。这种精心设计的方法从源头上保证了需求的高质量,也需要医院内部的执行者和协调者强有力的支持。

--

前面的话题主要涉及领域知识的重要性,下面我们回到建模上面来吧,至少从软件工程的视角,建模是解决领域知识整理和表达问题的有效途径。当然,我们不能期望把所有领域知识都放在模型里面,特别是有些被称为行业经验的部分,通常这些部分是灰色的,或者在政策上就无法在正式文档中记录的。

谈到领域建模,很多人会联想到领域驱动设计(DDD)。这年头能驱动设计的东西实在太多了,比如测试驱动(关注质量),比如配置驱动(关注变化点/灵活性),但每种驱动其实只是关注点不同而已,真正的实践则需要在所有这些关注点之间进行权衡,用老毛的说法就是识别主要矛盾和次要矛盾。一些批评者认为DDD容易导致领域模型和实现模型(即代码)之间过于直接的映射,使得代码太过关注业务复杂性,而过多地依赖一些繁琐的机制(如ORM)来屏蔽技术复杂性,造成性能和可维护性等方面的种种问题。这让我想起瀑布模型一直以来蒙受的不白之冤:其实作者在提出瀑布模型的论文中,就已经提到了各个阶段之间反馈和迭代的必要性,却被大多数敏捷支持者无意或故意的断章取义了。真不知道软件行业中屡见不鲜的这种怪圈,是不是传播学里面的正常现象。

总之,大多数实践者还是公认,在设计数据库和设计用户界面之前,都应该先建立能够反映领域和业务需求的对象模型,并由对象模型推导岀GUI和DB的设计。特别需要注意的是,当你设计对象模型的时候,你的关注点是业务需求(或者领域需求),而不是软件产品需求(仅作为设计约束),否则你模型将难以应对需求变化。

我宁愿把建模理解为一种脑力素描。素描是把眼睛看到的东西平面化到纸上,需要采用透视和光线明暗等方法论;建模是把理解到的东西抽象化到纸上,需要采用面向对象的方法论,除此以外目前暂时还没有其它成熟的方法体系。如果说素描是建筑设计师的基本功,那建模应该是软件设计师的基本功。

当然,真正意义上的建模也许更像写意(或者至少是中国画式的多点透视)。模型只是反映了建模者自身对问题的理解,而不是单纯地对现实世界的人、物体和组织的关系进行客观描绘,也许这些人造的东西,本来就很难进行客观描绘。但问题是,你如果不能尽可能客观地把问题描绘出来,软件开发就会偏离方向,最后做出来的东西根本不是客户想要的。至少在现阶段,机器不能真正进行“学习”的时候,软件唯一能做的只是把问题的描述映射成为技术的方案,问题描述错了,方案也就错了,这也就是为什么大部分的软件项目失败,都会归因于需求问题的原因。

然而,Martin Fowler(下面简称MF)的一句话,讲得很深刻:所有的模型都是错误的,但只有少数是有用的。

于是我们进一步推敲,如何验证一个模型是有用的呢?难道唯一的验证方法就是把它实现出来,然后看看这个软件能否被客户认可吗?但模型是否有用也不是软件能否被客户认可的充分条件啊。也许,就像软件设计的验证方法只能停留在学术圈一样,领域模型和其他脑力产品一样,只能做评估,而难以做验证的了。所以,对于MF在它的《分析模式》中提出的把分析人员跟技术人员完全分开的观点,我还是心存怀疑,因为模型就是为代码服务的,不会写代码的人,我认为难以设计出有用的模型。当然,如果你有一个建模团队,你完全可以也非常必要邀请几个纯粹的业务专家,但一定不能没有懂软件的人。

--

面向对象已经成为一种公认的分析和设计方法论,使用这个方法的经验被总结成各种模式。虽然看起来有点荒唐,有些经典模式甚至已经成为考核软件人员知识结构的硬性指标。比如,你要做程序员,就不能不读GoF的《设计模式》;你要做分析人员,就不能不读MF的《分析模式》。这里的分析人员,包括领域和业务分析,也包括需求分析。而且,领域分析是需求分析的基础。不过很多人根本没有意识到这一点,所以老在抱怨怎么客户需求老在变,程序老是改不完。如果他们留意一下需求变更的轨迹,会发现它是向心运动,而那个稳定的核心就是领域模型和业务需求。

有点遗憾的是,《分析模式》写于90年代,里面没有采用现在流行的UML,而且行文中充斥着太多抽象的概念,读起来有点困难。但至少对于医疗行业的软件人员来说,花费一点脑力还是值得的,至少书中很多地方都使用了医疗领域的案例,这些案例所涉及的模式基本上涵盖了医疗信息系统中所有关键部件的业务模型。当你碰到一些复杂的需求,分析起来一筹莫展的时候,这本书可能会让你眼前一亮。

同时,关注医疗信息集成的读者应该也能从中受益菲浅。对于各种医疗行业标准和集成规范,要做到灵活运用,必须理解标准中各种规定背后的原理,即制定者为什么要做那些规定。如果说了解分布式系统的原理就能理解标准中通信部分的原理的话,那么这些分析模式则可帮助我们理解对象模型部分的原理。理解并灵活运用这些原理之后,你就不再只是这些标准的消费者,更可以成为贡献者。如果你觉得成为贡献者似乎有点不可思议,因为这里面还有太多机缘巧合的因素,但至少当你接到某个新项目,这个项目所涉及的领域在HL7对象模型中没有给出具体规范,需要你根据参考模型开发自己的模型的时候,这些面向对象的分析技巧会大大提高你的效率。

另外,书中对于三层架构的解释也让人印象深刻。为什么本来应该属于业务逻辑的代码,我们不得不放到数据库里面去做,比如通过字段约束、存储过程、触发器等方式,这似乎破坏了业务层和数据层的界限,但确实我们没有必要重新开发一套支持企业级特性的事务和并发控制系统。所以大多数时候,我们只能容忍这样的耦合,并且把你的数据库脚本也视为一个关键的配置项进行管理,就算你采用了ORM之类的技术试图降低这种耦合,也还是要注意。同时,由于DBMS帮我们解决了很多并发控制的问题,使得很多信息系统的开发者忘记了并发的概念,就像以前面试过不少做Web开发的程序员,很少能讲得出ASP.Net的线程模型一样。

不过,我觉得书中最有价值的观点在于:不同业务领域之间的建模方法和经验,可以相互学习和重用。比如作者把他在医疗领域发现的观察模式应用到财务领域的成功案例。

(关于这个观察模式,作者不光把患者主述、症状和检查结果,甚至把诊断和预后,都泛化到“观察”概念下面,不知道是不是西方医学严谨循证精神的体现,但对于我来说,还是一个很值得细细品味的想法。记得不久前翻过一本叫做《医生该如何思考》的书,作者用絮絮叨叨的语言分析了临床决策的过程,现在读到MF的观察模式,之前作者指出的医学的本质——一门依赖于临床推理的解释性实践——居然被概括到几个简洁的框图里面,在似曾相识的同时,也让人看到了模型的力量。)

可能由于对《分析模式》理解不深,不知道里面有没有提到关于“时间”概念在业务模型中的处理,或者这里面存在着一种MF尚未涉及的场景:很多业务模型中的实体、关系和约束可能会随着时间变化的,比如人事系统中的部门和员工,其中的雇用关系或汇报关系可能会随着内部调动或离职而变更;销售系统中的产品和价格,可能会有产品上架下架,产品的价格也在调整,但用户任何时候去查看历史上任何一个时间段的销售日报、周报和月报,它们都必须反映当时的真实情况。

有数据库设计经验的人,可能会想到是否需要在每个表都添加一个时间字段,使得产品和价格在时间上展开成一对多的关系。或者干脆每个年度使用一套表,就像一本台账。比如每年年初对员工和部门之间的雇用关系,及其工作目标和考核指标进行初始化。在该年度中,这些基础数据正好能够支持系统中各种业务功能,台账的概念则有效实现和封装了这些基础数据的时间局部性。我们不排除年中会有新员工入职,并且可以通过添加新的基础数据来实现;但到了年末,则需要封账,使得所有这些数据变为只读,仅供查询统计使用,必要时甚至可以把这些只读数据转入低成本的存储器,比如移到离线,或进行压缩。但台账只是流水帐,在银行系统中可能还需要分户账,比如台账记录账户的日常收入支出,分户账记录当前的结算金额,这有效低降低了时效性数据带来复杂性,特别当你需要进行一些不带时间参数(比如对取款金额和余额进行比较)或跨越多个时间段(如统计报表)的业务运算的时候。

总之,当你把时间概念考虑进来以后,业务模型会变得复杂很多,也更能反映真实世界。特别是对于需要长期存储病人或居民信息的EMR和EHR,时间也是一个重要的数据存储索引和重要的数据展示坐标(在国家的建设指南中,EHR索引被要求按照面向时间、面向问题和面向机构活动的方式来建立)。但我们这里讨论的“时间”概念,可能更加关注一些基础数据的变化对系统的影响,比如医疗卫生单位的人员和机构的变化、系统用户的变化(比如删除用户的时候不能破坏操作日志的完整性)等。这些变化不是周期性的,也难以使用类似财务系统的方式来解决,但在的医疗领域,对于观察和处理过程的记录和追查同样十分重要。因此,其中一种方式是,容忍一些信息集合的局部性(这种局部性可能是时间上的,或者空间上的),并且用交叉索引的方式把它们关联起来。作为医疗领域基础数据集重要组成部分的各种编码系统,则采用了另一种方式:码值在存储和传输的时候,都会带上一个编码系统的标识,其中可以包含版本号。这个版本号反映了该编码系统中包含的知识领域模型(用《分析模式》中的术语)随着时间的变化情况,让你可以在必要的时候进行编码系统映射。

--

前面似乎虚的东西讲得比较多,最后来点实的。下面是现阶段我对电子健康档案的一些理解,仅代表个人观点,如有异议,感谢赐教,如有雷同,纯属巧合。

1. 关于数据

业界很多人在EHR和EMR中应该放什么的数据这个问题上争论不休,其实这是个业务领域问题或医疗信息管理问题,属于医院或卫生局的信息部门考虑的范围。如果你是解决方案提供商或软件开发商,你确实需要关注的它们,但这些问题并不是你的考虑范围。

对于软件开发者来说,则需要在弄清楚医疗信息管理领域的核心模型和基本业务规律的基础之上,提供出能够存储可预见的各种医疗信息的系统。况且,这些医疗信息的种类和数量一直都在不断变化之中,你考虑什么该放什么不该放意义不大,你考虑的应该是这些数据的核心模型是什么?现在最少需要放哪些?如果将来要放别的,如何以最低的成本实现扩展?

关于核心的数据模型,前人已经做了大量的工作,比如非常有名的HL7 RIM,最近甚至还在提RIM Based Application Architecture(RIMBAA)。不过这个方法本身也面临不少争论,毕竟HL7 RIM还是以消息通信为目的建立的模型,按照MF的说法,所有模型都是错的,只不过它被证明了在互操作领域有用而已。HL7 RIM及其消息模型显然是集成(特别是跟其他厂商集成)接口设计的不二选择,但是对于EHR内部的数据模型,明智的开发者应该会有自己的考虑。

2. 关于组件

在技术抽象上,EHR和EMR二者的核心组件十分相似,一般可以划分成四类,1、数据收集和集成;2、数据存储;3、数据展示;4、数据处理和医疗智能。数据收集和集成组件负责数据的多向流转,是把死档变成活档的关键;活了之后还要变聪明,就得靠数据处理和医疗智能应用;数据展示要跟数据存储紧密配合,才能够支持海量数据的安全和高速的访问。

对于EMR来说,在以上四类组件的基础上,还多了一个功能复杂的病历编辑界面,配以丰富的模版和聪明的临床提示支持。但EHR基本上不需要输入界面,反而更像一个数据存储和共享的平台,比如就算是来自初级医疗部门的针对健康人的卫生服务记录,也应该由社区卫生系统上传过来,而不是在EHR上直接录入。社区卫生系统或全科诊所系统内部可能也需要一个以病人为中心的存储组件,来保存诊疗或服务记录。你叫做EMR也行,叫做病案模块也罢。总之按照现在国内的做法,社区卫生系统基本上也就是简化版的医院信息系统,再加上慢病管理计划免疫等模块而已。在里面包含一个病案存储并不复杂,而且在基于互联网的分布式系统中,维持一份常用数据的本地拷贝也是十分重要的。

对于数据展示模块,不同的医护人员需要不同的门户,这是没错的,可以通过两种策略进行实现:1、为不同的角色开发不同版本的门户模块;2、实现可按照角色进行个性化订制的门户模块。不管是对于EMR门户还是EHR门户,都需要把这两种实现策略结合起来使用,以便在可用性和实现成本之间取得平衡。同时由于医改过程中很多可变的因素,还不能对于医生的信息显示需求做出太过具体的假设,比如不能简单的以为外科医生只关注X光片,而不需要知道患者的慢病病史;也不能简单的以为全科医生只需要得到医院最终的诊断结论和治疗意见,而不必看到X光片和手术记录。

3. 关于技术

在企业级(比如医院或诊所内部)的计算环境下,三层甚至二层结构的信息系统,加上基于关系模型的数据存储,已经基本够用。也就是说大部分的EMR都可以采用这样的架构策略来实现,但EHR,以及大型集团医院的EMR,个人认为迟早要切换到云计算的模式上来。现在市场上云计算的概念营销,都是很多卖服务器的厂商唱主角,所以很多人都以为云计算就是虚拟化。但对于应用软件开发者来说,云计算的代表性技术则是所谓的Google三架马车:MapReduce,DFS(分布式文件系统)和BigTable。我想如果将来《分析模式》要出第二版,那么以这些技术所代表的编程模型将会成为一种新的支持模式,跟现有的多层架构模式并列;同时可能会提到,DFS和BigTable将会成为EHR存储和EHR索引的载体,而MapReduce则统一了EHR平台上大部分数据存储、交换和处理的编程模型。

所以现在的问题就变成:如何以最低的成本获得这些新技术。有两种方式:1、主动拥抱这些新技术,研究开源代码并加以运用;2、等待微软或甲骨文之类的大厂商把这些技术融合到他们的产品中,然后购买他们的产品。现在关系数据库和NoSQL存储技术已经在互相学习,取长补短。习惯于抄袭的微软,会不会也弄出一个能够独立发布的分布式存储系统来呢?有时,他们的抄袭反而使得某些技术的获取成本大大减低了。

阅读更多
换一批

没有更多推荐了,返回首页